Skip to content

fix(sse): scope dispose to per-screen provider instance#2271

Merged
sharjeelyunus merged 3 commits into
mainfrom
cursor/critical-bug-remediation-d916
Jun 10, 2026
Merged

fix(sse): scope dispose to per-screen provider instance#2271
sharjeelyunus merged 3 commits into
mainfrom
cursor/critical-bug-remediation-d916

Conversation

@cursor

@cursor cursor Bot commented Jun 10, 2026

Copy link
Copy Markdown

Bug and impact

Trigger: A screen with SSE configured in api_providers is disposed while another screen still has an active SSE subscription — e.g. closing a modal, navigating back, or switching bottom-nav tabs when reloadView: true (default).

Impact: SSEAPIProvider.dispose() cleared static subscription/client maps shared app-wide. Disposing one screen silently killed every SSE stream, leaving still-mounted screens with stale bindings and no live updates.

Root cause

  • _subscriptions and _activeClients were static, but each Screen clones and disposes its own APIProvider instances on unmount.
  • APIProviders.getProvider('sse') allocated a new SSEAPIProvider() on every lookup instead of using the per-screen cloned instance from the provider map.

Fix

  • Make SSE subscription/client state instance-scoped (same pattern as FirestoreAPIProvider).
  • dispose() now cancels only subscriptions owned by that provider instance.
  • getProvider('sse') returns providers['sse'] when present so subscribe/dispose use the same instance.

Validation

  • Added modules/ensemble/test/sse_provider_dispose_test.dart covering per-instance dispose isolation and getProvider('sse') map resolution.
  • Run from modules/ensemble: flutter test test/sse_provider_dispose_test.dart

Duplicate check

Open in Web View Automation 

SSE subscriptions and HTTP clients were stored in static maps but
Screen.dispose() calls dispose on cloned API providers. Disposing any
screen cancelled every SSE connection app-wide, breaking live streams on
still-mounted screens after navigation, modals, or tab switches.

Make subscription state instance-scoped (matching FirestoreAPIProvider)
and resolve getProvider('sse') from the screen provider map instead of
allocating a throwaway instance on each lookup.

Co-authored-by: Sharjeel Yunus <sharjeelyunus@users.noreply.github.com>
Comment thread modules/ensemble/lib/framework/apiproviders/api_provider.dart Outdated
sharjeelyunus and others added 2 commits June 11, 2026 00:27
…on handling

Updated the APIProviders class to utilize a map for provider resolution, ensuring a fallback to SSEAPIProvider when necessary. Additionally, modified the SSE provider tests to verify cancellation behavior of StreamControllers, ensuring proper resource management during disposal.
@sharjeelyunus sharjeelyunus marked this pull request as ready for review June 10, 2026 21:02
@sharjeelyunus sharjeelyunus merged commit cc167ab into main Jun 10, 2026
5 checks passed
@sharjeelyunus sharjeelyunus deleted the cursor/critical-bug-remediation-d916 branch June 10, 2026 21:03
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