Skip to content

Keep the in-flight guard on the current timeline poll - #622

Merged
Birfy merged 1 commit into
ThinkFlowLab:mainfrom
HugoXK:fix/timeline-poll-inflight
Oct 21, 2026
Merged

Birfy merged 1 commit into
ThinkFlowLab:mainfrom
HugoXK:fix/timeline-poll-inflight

Conversation

@HugoXK

@HugoXK HugoXK commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

Keep the in-flight guard on the current timeline poll
The timeline panel's poller (plugins/timeline/client.js) cleared inFlight in a finally that ran even for a request the window change had superseded. restart() (a window change, refresh, or coming back to the tab) bumps generation, clears inFlight and starts the replacement, so when the superseded answer landed it cleared the flag of the request that had replaced it. With the guard reading false while a request was genuinely in flight, the visibility watcher (if (... && !inFlight) restart()) started a third request — the "one request in flight" rule of timeline.md invariant 7 was broken and the host could be polled twice over.
inFlight is now cleared only when the request still owns its generation, so a superseded answer leaves the replacement's guard alone. plugins/timeline/test/client.test.js opens a panel, refreshes (superseding the first request), lets the superseded answer arrive, fires the visibility watcher and asserts no third request is issued — it fails without the change (the count reaches 3).
Ran at the tip: npm run verify (green, TZ=UTC). Not run: smoke (this macOS box has no setsid, so dev/bench.sh cannot start dsh web), Desktop, real-model steward.

The timeline poller's finally cleared `inFlight` unconditionally, so a
request the window change superseded cleared the flag while the request
that replaced it was still in flight. Coming back to the tab then
started a third request, breaking the one-request-in-flight rule. Clear
the flag only when the request still owns the generation.
@Birfy Birfy added area:automation Scheduled tasks and automation area:ui Web/desktop UI and copy bug Something isn't working labels Oct 21, 2026
@Birfy

Birfy commented Oct 21, 2026

Copy link
Copy Markdown
Collaborator

Verdict: PASS at eb034e5

Tip SHA: eb034e5ffbee3909da02ad3223a9b64429c3f006
CI at tip: 8/8 success (tests-ok, package, plugins social/tree/timeline, ubuntu-latest Node 24,
           reviewed tip, risk tier)
Tier (from the diff): T2 — plugins/** (plugins/timeline/client.js)

Ran at this tip:

$ cd plugins/timeline && TZ=UTC node --import ./test/resolve.mjs --test test/client.test.js
# tests 12 / pass 12 / fail 0

Gate ③, source change reverted (plugins/timeline/client.js from main 3995d9b9), tests kept:

not ok 5 - a superseded request does not drop the in-flight guard of the one that replaced it
# tests 12 / pass 11 / fail 1

Exactly the one new test goes red.

The mechanism checks out: restart() bumps generation, clears inFlight and starts the replacement (which sets inFlight = true again), so a superseded request's finally used to clear the flag the replacement had set — the visibility watcher then saw "nothing in flight" and started a third request. Guarding the finally with mine === generation is the smallest correct fix and leaves the backoff/schedule path alone, which the other 11 tests pin.

Entering the merge queue now.

@Birfy
Birfy added this pull request to the merge queue Oct 21, 2026
Merged via the queue into ThinkFlowLab:main with commit 1f4024b Oct 21, 2026
8 checks passed
@Birfy

Birfy commented Oct 21, 2026

Copy link
Copy Markdown
Collaborator

Post-merge record: 1f4024be (squash, via the merge queue). Reviewed tip eb034e5f unchanged.

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

Labels

area:automation Scheduled tasks and automation area:ui Web/desktop UI and copy bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants