Add multi-consumer pause-reason API to SDK root#204
Merged
Conversation
The `paused` attribute on the SDK root used to be set directly by each independent caller — a UI hover toggle, an open modal, a long-running export. Whichever caller flipped last won, and the "last flipped" was often the wrong one: e.g., when the cursor moved from the topology canvas onto an open actor modal, the topology hover-end fired and wrote `paused: false`, releasing the modal's still-active pause. Updates resumed underneath the modal, re-fetched data, and the tables / mini-topology jittered every tick. Fix: the SDK root now owns a private `pauseReasons` Set and exposes `addPauseReason(reasonId)` / `removePauseReason(reasonId)`. The `paused` attribute is recomputed as `blurReason || pauseReasons.size > 0` whenever a reason is added / removed OR when the blur sources (`blurred`, `autofetchOnWindowBlur`) change. Reasons compose: hover-end removes its own id and leaves the modal's id in place, so the aggregate stays true while the modal is open. Idempotent on the same reason id, no-op for empty/missing ids, fully cleared on `destroy()`. 8 new tests in `makeNode.test.js` cover the aggregation, blur combination, idempotency, and the original clobber-bug regression (remove-one keeps aggregate true while another remains). Downstream: `@netdata/cloud-frontend`'s `usePauseSDK` hook moves from its own module-level Set to this SDK API in a parallel PR.
novykh
approved these changes
May 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The SDK root's
pausedattribute was being written directly by eachcaller — a UI hover toggle, an open modal, a long-running export.
Whichever caller flipped last won, and the "last flipped" was often
the wrong one: e.g., when the cursor moved from a topology canvas
onto an open actor modal, the canvas hover-end fired and wrote
paused: false, releasing the modal's still-active pause intent.Updates resumed underneath the modal, tables and the mini-topology
jittered on every refresh tick.
The fix is multi-consumer pause-reason aggregation INSIDE the SDK,
exposed on every node via
addPauseReason/removePauseReason.Reasons compose: hover-end removes its own id and leaves the modal's
id in place, the aggregate stays true while the modal is open.
API
node.addPauseReason(reasonId)— registers an opaque reason id.node.removePauseReason(reasonId)— removes it.pausedis auto-recomputed asblurReason || pauseReasons.size > 0whenever a reason is added/removed OR when the blur sources (
blurred,autofetchOnWindowBlur) change.cleared on
destroy().Downstream
@netdata/cloud-frontend'susePauseSDKhook moves from its ownmodule-level Set to this API in netdata/cloud-frontend#5520. After
that PR lands and the SDK ships a version with this change, the
cloud-frontend hook becomes a thin wrapper that just pushes/pulls
its
useId()through the SDK API.Tests
8 new tests in
src/sdk/makeNode.test.jscover the aggregation,blur combination, idempotency, empty-id handling, and the original
clobber-bug regression (remove-one keeps aggregate true while
another remains).
Test plan
yarn test src/sdk/makeNode.test.jspassesthey continue to write
pauseddirectly viaupdateAttribute(the new API only adds reasons to a privateSet; direct attribute writes still work the same way)
the browser: open the actor modal on a topology view, move the
cursor onto the modal, confirm updates STAY paused