Skip to content

feat(hooks): real-time task updates with SSE fallback polling (#233)#440

Open
Shikhar-404exe wants to merge 1 commit into
utksh1:mainfrom
Shikhar-404exe:233
Open

feat(hooks): real-time task updates with SSE fallback polling (#233)#440
Shikhar-404exe wants to merge 1 commit into
utksh1:mainfrom
Shikhar-404exe:233

Conversation

@Shikhar-404exe
Copy link
Copy Markdown
Contributor

Summary #233

Adds a reusable useTaskSubscription hook that provides real-time task status and output
updates via Server-Sent Events (SSE), with automatic polling fallback when the SSE connection
drops. Replaces the inline EventSource logic in TaskDetails.tsx.

Changes

New: useTaskSubscription hook (frontend/src/hooks/useTaskSubscription.ts)

  • Connects to GET /api/v1/task/{task_id}/stream via EventSource
  • Listens for status and output events, deduplicating identical values
  • On SSE error: exponential backoff reconnect (1s, 2s, 4s, 8s, 16s — max 5 attempts),
    then falls back to polling getTaskStatus() at a configurable interval
  • On terminal status (completed/failed/cancelled): cleans up EventSource, timers, and polling
  • Returns { isConnected, isPolling, error } for UI indicators

Refactored: TaskDetails.tsx

  • Inline EventSource setup removed; replaced with useTaskSubscription
  • loadTask() is called on mount and when terminal status arrives

Tests (useTaskSubscription.test.ts)

  • SSE connection on mount, status/output event callbacks
  • Deduplication of identical status values and output chunks
  • Reconnect with exponential backoff and max attempt limit
  • Polling fallback after reconnect exhaustion
  • Polling at configured interval
  • Stop polling on terminal status
  • Cleanup on unmount

Key design decisions

  • reconnectAttemptRef is only reset on onopen (successful connection), not inside
    connectSSE(), so consecutive reconnect failures properly accumulate toward the max limit
  • Ref-based callbacks (onStatusRef, onOutputRef) avoid stale closures
  • cleanupRef gate prevents race conditions during teardown
  • Polling uses setInterval with cleanup checks both before and after the async fetch

…#233)

- useTaskSubscription hook with EventSource SSE, reconnect with
  exponential backoff, polling fallback after max retries
- Deduplicates identical status values and output chunks
- TaskDetails.tsx refactored to use the hook, removed inline SSE logic
- 12 hook tests: SSE events, dedup, reconnect, polling, terminal stop, cleanup
- reconnectAttemptRef reset only on successful open (not on reconnect call)
@utksh1 utksh1 added level:intermediate 35 pts difficulty label for moderate contributor PRs type:testing Testing work category bonus label type:feature Feature work category bonus label area:frontend Frontend React/UI work labels May 31, 2026
Copy link
Copy Markdown
Owner

@utksh1 utksh1 left a comment

Choose a reason for hiding this comment

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

Thanks for extracting the task subscription hook. This needs one correctness fix before merge: deduplicating output by identical chunk content can drop legitimate repeated scanner output lines. Please preserve output stream order exactly, only dedupe status/phase if needed, and add a regression where two identical output chunks are both appended.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:frontend Frontend React/UI work level:intermediate 35 pts difficulty label for moderate contributor PRs type:feature Feature work category bonus label type:testing Testing work category bonus label

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants