Skip to content

fix(#1138): fix SSE EventSource leak and polling race condition (duplicate, conflicts resolved)#1234

Merged
utksh1 merged 3 commits into
utksh1:mainfrom
ionfwsrijan:duplicate/pr-1174-sse-polling-race
Jun 24, 2026
Merged

fix(#1138): fix SSE EventSource leak and polling race condition (duplicate, conflicts resolved)#1234
utksh1 merged 3 commits into
utksh1:mainfrom
ionfwsrijan:duplicate/pr-1174-sse-polling-race

Conversation

@ionfwsrijan

@ionfwsrijan ionfwsrijan commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Duplicate of #1174 with merge conflicts resolved and rebased onto latest main.

Problem

  1. SSE EventSource leak: On reconnect, the es.onerror handler could fire
    for the old EventSource after a new connection was established, triggering
    spurious reconnection loops and duplicate EventSources.
  2. Polling race: setInterval(loadTasks, 5000) in Scans.tsx doesn't await
    the async loadTasks(). If a request takes longer than 5s, overlapping
    requests pile up, potentially corrupting state.

Solution

  • Added a versionRef (generation counter) to useTaskSubscription.ts that
    increments on every connectSSE() call and every cleanupAll()
  • All SSE callbacks (status, phase, output, onerror, onopen) now check
    versionRef.current === expectedVersion before acting — stale callbacks from
    previous connections are silently ignored
  • In Scans.tsx, replaced setInterval with chained setTimeout:
    scheduleNextPoll() awaits loadTasks() before scheduling the next tick
  • Renamed intervalRefpollingTimerRef for clarity

Files changed

frontend/src/hooks/useTaskSubscription.ts, frontend/src/pages/Scans.tsx

Closes #1138

- Add version/generation counter in useTaskSubscription to prevent stale
  EventSource callbacks from triggering after reconnection
- Check versionRef.current against expected version in all SSE event handlers,
  onerror, and onopen to ignore callbacks from previous connections
- Replace setInterval in Scans.tsx with chained setTimeout that awaits
  loadTasks() before scheduling the next poll
- Use AbortController signal to gate polling continuation
- Rename intervalRef to pollingTimerRef for clarity
…eout

The chained setTimeout pattern calls poll() once immediately on start,
unlike setInterval which waits for the first interval. Update the test
assertions to reflect the correct call counts.
@ionfwsrijan

Copy link
Copy Markdown
Contributor Author

@utksh1 Please review this now

@utksh1 utksh1 merged commit b529ddb into utksh1:main Jun 24, 2026
9 of 10 checks passed
@utksh1 utksh1 added the gssoc:approved Admin validation: approved for GSSoC scoring label Jun 24, 2026
@ionfwsrijan

Copy link
Copy Markdown
Contributor Author

@utksh1 Please add other labels

utksh1 added a commit that referenced this pull request Jun 25, 2026
, #1234, #1232, #1231, #1230, #1229, #1228, #1222, #1221, #1254, #1252, #1251, #1250, #1242, #1255, #1090, #1097, #1112)

Reverting all PR merges performed during this session to restore repository
to pre-session state. This reverts commits:
- e376276 (#1255)
- 18e5101 (#1222)
- e516dd5 (#1230)
- be400fa (#1235)
- d522e9a (#1243)
- bc0b1cd (#1090)
- de56660 (#1097)
- c2a5a53 (#1112)
- eb30d33 (#1254)
- f2a67f7 (#1250)
- 6579112 (#1251)
- 8751d92 (#1252)
- 3ebc935 (#1221)
- 6f5a936 (#1228)
- da15da4 (#1229)
- b66a5b0 (#1231)
- 775c5c2 (#1232)
- b529ddb (#1234)
- 965b001 (#1241)
- d46e573 (#1242)
- dd09955 (#1240)

All PRs are also being reopened and gssoc labels removed.
@utksh1 utksh1 added level:intermediate 35 pts difficulty label for moderate contributor PRs type:bug Bug fix work category bonus label area:frontend Frontend React/UI work area:backend Backend API, database, or service work gssoc:approved Admin validation: approved for GSSoC scoring and removed gssoc:approved Admin validation: approved for GSSoC scoring labels Jun 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:backend Backend API, database, or service work area:frontend Frontend React/UI work gssoc:approved Admin validation: approved for GSSoC scoring level:intermediate 35 pts difficulty label for moderate contributor PRs type:bug Bug fix work category bonus label

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] SSE Connection Leak in useTaskSubscription Combined with Polling Race in Scans Page

2 participants