Skip to content

Keep state polls from overwriting newer edits and tab switches - #242

Merged
SchrodingersCattt merged 3 commits into
mainfrom
cursor/poll-edit-tab-race-f72a
Oct 26, 2026
Merged

SchrodingersCattt merged 3 commits into
mainfrom
cursor/poll-edit-tab-race-f72a

Conversation

@SchrodingersCattt

@SchrodingersCattt SchrodingersCattt commented Oct 25, 2026 •

Copy link
Copy Markdown
Owner

Summary

Part of #228.

agent-state-poll could still publish a snapshot that was frozen before the browser switched scenes or edited. Sidebar drafts already visible in that request stayed put (#229). Groups, transforms, polyhedra, selection, and the filled-scene guard did not.

This covers the remaining high-severity checkbox on #228: agent-state-poll races user edits and tab switches (the rename box and in-flight sidebar path are already handled by #226 and #229).

  • Each browser records the scene it selected and the interaction generation of its latest edit. A poll for a scene that browser has left, or for an older generation, returns no update. It does not move the filled-scene guard and does not drop a queued snapshot it cannot publish.
  • The browser drops a pure state-poll response that arrives after a tab switch or edit, and a poll that was sent while that callback is still unacknowledged. A tab switch or upload batched into the same request still applies. camera-state-store stays untouched on the poll path.
  • The first Dash callback runs at generation 0. That generation still releases the in-flight count, so a later edit does not leave state polls blank. Those polls are what copy a server projection onto the view radio and refresh the controls stamp.
  • Calls that do not send the fence (existing direct tests) keep the previous contract, including in-flight sidebar drafts and the rename box.

This does not address #163. The figure-settle latency item on #228 remains.

Test plan

  • python3 -m pytest tests/app/test_poll_interaction_fence.py
  • Local Camera WebGL suite: the six previously red settle cases pass. tests/app/test_camera_browser_regression.py, tests/app/test_real_app_browser_regression.py, and tests/app/test_layout_responsive.py — 25 passed, and test_two_browsers_keep_separate_scenes_during_upload passed on a rerun after one isolated miss in the full local run.
Open in Web Open in Cursor 

cursoragent and others added 2 commits October 25, 2026 15:55
Part of #228. A poll that left the browser before a tab switch or edit,
or that is answered while that callback is still open, no longer writes
sidebar controls or agent-state-store for that browser. In-flight
sidebar drafts and the rename box stay as they were.

Co-authored-by: Ming-Yu Guo <guomy26@mail2.sysu.edu.cn>
The fallback layout and the main layout both need the same hidden
epoch, client id, and acknowledgement sink. One helper keeps the app
factory within its line cap.

Co-authored-by: Ming-Yu Guo <guomy26@mail2.sysu.edu.cn>

@SchrodingersCattt SchrodingersCattt left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Review @ 39305c28 (Part of #228)

Verdict: approve-ready pending remaining CI (COMMENT only; no self-APPROVE).

What looks right

  • Covers the open high Latency checkbox after #226/#229: server-side scene + interaction-generation fence (poll_request_is_stale / claim_poll_publish) plus browser poll_fence.js for responses that race an in-flight tab switch/edit.
  • Pure poll vs batched tab-switch/upload distinction is clear; camera store left alone on the poll path; rename / in-flight sidebar drafts left as #226/#229.
  • Wording avoids GitHub auto-close keywords for #163 (does not address #163).
  • Focused tests in tests/app/test_poll_interaction_fence.py; agent reported local 1990 passed / 70 skipped.

CI at review time

5/9 green (build, bench smoke, fast×2, CPU smoke). Still running: Full tests 3.10/3.11/3.12 + Camera WebGL. Agent says WebGL path untouched — still wait for green before merge.

Hold

Do not squash-merge until all 9 checks are green. Figure-settle / busy-pill remains on #237.

A generation of 0 is a real Dash callback. Treating it as absent counted
that callback and never released it, so later edits left state polls
blank for the rest of the page. Those polls copy a server projection
onto the view radio and refresh the controls stamp.

Part of #228.

Co-authored-by: Ming-Yu Guo <guomy26@mail2.sysu.edu.cn>
@SchrodingersCattt
SchrodingersCattt merged commit 44ceb8f into main Oct 26, 2026
9 checks passed
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