Skip to content

fix(store): keep observeSignal alive past views - #6030

Merged
norman-abramovitz merged 3 commits into
cloudfoundry:developfrom
nabramovitz:norm/fix/observe-signal-lifetime
Oct 20, 2026
Merged

norman-abramovitz merged 3 commits into
cloudfoundry:developfrom
nabramovitz:norm/fix/observe-signal-lifetime

Conversation

@nabramovitz

Copy link
Copy Markdown
Contributor

Follow-up to #6026.

observeSignal (store signal-interop.ts) bridges a signal to an observable with an effect it destroys on unsubscribe. Given a component's injector, that effect was a view effect: it ended with the view, manualCleanup or not, and the observable then went silent without completing. A subscriber that outlived the view (a stepper promise, a snackbar action) would wait forever.

An audit of the 20 callers found none that outlives its view today. Four root services are re-provided by components (CfRolesService, the CF org/space services, HelmReleaseHelperService, KubernetesNodeService), so their bridges get a component's injector, and a future subscriber of theirs would hang without a trace.

  • fix(store): the effect is created on the injector's EnvironmentInjector, so it lives exactly as long as the subscription. A subscriber that must stop with a view unsubscribes itself.
  • fix(helm): with that change, the upgrade page's constructor subscription to the upgrade target would outlive the page and set up the version list on a destroyed component. It now ends with the component (takeUntilDestroyed). Its spec now replaces the component's own HelmReleaseHelperService, so the mock is the one the component uses.

Each fix has a test that fails before it.

Release note: changelog.d/0014-observe-signal-lifetime.md.

AI disclosure (RFC-0047): prepared with AI coding assistance; reviewed by the author.

The upgrade target can resolve after the user leaves the upgrade page.
The constructor subscription was never ended, so a late value set up
the version list and loaded versions on a destroyed component. End it
with the component (takeUntilDestroyed).

The spec now swaps the component's own HelmReleaseHelperService, so
the mock is the one the component uses.
With a component's injector, observeSignal made a view effect. It
ended with that view and left the observable silent, never complete,
so a subscriber that outlived the view (a stepper promise, a snackbar
action) would hang. Create the effect on the injector's
EnvironmentInjector, so it lives exactly as long as the subscription.
Release note for the signal helper and Helm upgrade fixes.

@norman-abramovitz norman-abramovitz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - Need to see if change will cause issues because the cache needs to be updated

@norman-abramovitz
norman-abramovitz merged commit 43e55a1 into cloudfoundry:develop Oct 20, 2026
24 checks passed
@nabramovitz
nabramovitz deleted the norm/fix/observe-signal-lifetime branch October 20, 2026 08:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants