fix(tui): prevent stale status/fix-jobs responses from overwriting fresher data#598
fix(tui): prevent stale status/fix-jobs responses from overwriting fresher data#598cpcloud wants to merge 10 commits intoroborev-dev:mainfrom
Conversation
…esher data (roborev-dev#596) Add loadingStatus and loadingFixJobs in-flight guards matching the existing loadingJobs pattern. When a fetch is already in flight, handleTickMsg skips dispatching another, preventing overlapping requests from racing and overwriting fresher data with stale responses. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add startFetchStatus and startFetchFixJobs helpers that check the loading flag before dispatching. Use them at all call sites — tick handler, reconnect, view switch, fix trigger, and patch apply — so no path can launch a concurrent request while one is already in flight. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…tations On reconnect, force-reset loadingFixJobs and dispatch a fresh fetch (matching the existing status handling) so a stale in-flight request from the dead connection doesn't block all future fix-jobs fetches. For state-mutating handlers (fix enqueue, patch apply, rebase), use requestFetchFixJobs which sets a fixJobsStale flag when a fetch is already in flight. handleFixJobsMsg checks this flag and dispatches a follow-up fetch to pick up post-mutation state. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The fixJobsStale check already covers both success and error paths (it's outside the if/else), but add an explicit test to prove it. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Route fetchStatus/fetchFixJobs in handleSSEEventMsg and consumeSSEPendingRefresh through the startFetch helpers, consistent with the tick and reconnect paths. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
5e9a2d1 to
f90e1a1
Compare
roborev: Combined Review (
|
SSE events signal daemon state changes, so use requestFetchStatus and requestFetchFixJobs in the SSE handlers. When a fetch is already in flight, these set a stale flag so handleStatusMsg/handleFixJobsMsg dispatch a follow-up fetch to pick up post-event state. Also clear statusStale on reconnect to avoid stale follow-ups from the dead connection. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
roborev: Combined Review (
|
Increment a monotonic fetchGen counter on reconnect and embed it in statusMsg, statusErrMsg, and fixJobsMsg. Response handlers discard messages from older generations, preventing a late pre-reconnect response from overwriting post-reconnect state. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
roborev: Combined Review (
|
…flags Increment fetchSeq on reconnect so pre-reconnect job responses are also discarded (jobs already had seq-based staleness checking). Move loadingStatus/loadingFixJobs flag clearing after the fetchGen check so stale pre-reconnect responses don't clear the in-flight guard for the current-generation request. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Reset loadingMore during reconnect so a stale pre-reconnect pagination response (now discarded by fetchSeq) doesn't leave the flag stuck true, which would cause future tick/SSE refreshes to skip full job reloads. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
roborev: Combined Review (
|
Clear loadingFixJobs and fixJobsStale unconditionally on reconnect, not just when tasksWorkflowEnabled() is true. Prevents a stuck loadingFixJobs flag if a pre-reconnect request was in flight while tasks were disabled. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
roborev: Combined Review (
|
|
Failing CI is due to a race condition that I might've introduced in #595. Working on it now. |
Summary
Closes #596.
loadingStatusandloadingFixJobsin-flight guard booleans matching the existingloadingJobspattern, preventing overlapping tick-based fetches from racingstartFetchStatus()andstartFetchFixJobs()helpers that check the loading flag before dispatching, used at all call sites (tick, reconnect, view switch, fix trigger, patch apply)statusErrMsgtype so status fetch errors clear the loading flag instead of going through the genericerrMsghandlerrequestFetchFixJobs()for mutation handlers (fix enqueue, patch apply) that sets afixJobsStaledeferred-refresh flag when a fetch is already in flight —handleFixJobsMsgdispatches a follow-up fetch when this flag is setloadingFixJobson reconnect so a stale in-flight request from the dead connection doesn't block all future fix-jobs fetches🤖 Generated with Claude Code