Repository navigation
fix: sync shared-name storage vars in the writing tab (#7567) - #7637
Conversation
There was a problem hiding this comment.
All reported issues were addressed across 3 files
Reply with feedback, questions, or to request a fix.
View guided diff | Re-trigger cubic
d0cba9f to
d931987
Compare
d931987 to
344ae42
Compare
[Medium impact] The PR appears safe to merge; no new actionable issue was found. SummaryUpdates synced
The earlier browser-side findings no longer apply to the replacement approach. The backend also collects explicit writes before setting siblings, addressing the earlier overwrite finding. Reviews (8) · Last reviewed commit: "Sort shared storage groups by state and ..." · Reviewed by Greptile |
There was a problem hiding this comment.
All reported issues were addressed across 2 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
View guided diff | Re-trigger cubic
One delta writing two same-name vars with different values would queue a sync that excluded the earlier writer, leaving it on the old value while storage held the last write. Build the sync set from every synced var with the name, like handleStorage, so the last write converges all of them.
|
Hi @masenf, this is ready for a look when you have a moment. The workflows are waiting on first-time-contributor approval; the new state.js tests pass locally (37/37, and the new ones fail against the template on main). |
Merging this PR will not alter performance1 warning
Comparing |
|
The required app-harness workflow now fails I reduced it against the actual
The same-tab sync generated from an older response is being treated as a fresh write. This needs an ordering fix that preserves same-tab propagation and the existing cross-tab echo protection; simply suppressing every pending echo can also suppress legitimate updates whose backend delta was transformed. I have left the synchronization design to the author/reviewers and have not rerun the deterministic failure. |
Skip the sibling sync when any synced var sharing the storage name has an unechoed entry in sentStorageValues, so a stale delta cannot resend an older value while a newer update_vars_internal is in flight. Adds the Playwright regression test requested in review.
There was a problem hiding this comment.
All reported issues were addressed across 3 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
View guided diff | Re-trigger cubic
Replace the frontend same-tab sync with a backend fan-out. When an event writes a localStorage var, set the other synced vars with the same storage name in the same locked event, before the delta is resolved. The writing tab gets every sibling in one delta and sends no extra sync event. The frontend sync had to track sent values that the backend did not echo. A get_delta override that rewrites the echo left such a value behind, and the guard then suppressed the sibling sync for that name until reload. The backend fan-out keeps no per-tab state, so that cannot happen.
|
I changed the solution in this PR. The fix now sets the sibling vars on the backend, not from the frontend. Why: the frontend sync had to track sent values that the backend did not echo yet. A Now Tests: a new unit test and two Playwright tests (sibling sync and the override case) fail on |
There was a problem hiding this comment.
All reported issues were addressed across 7 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
View guided diff | Re-trigger cubic
When one event writes two synced vars with the same storage name, the fan-out set each to the other's value and lost one write. Collect the event's writes first and do not set a var the event wrote.
There was a problem hiding this comment.
All reported issues were addressed across 2 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
View guided diff | Re-trigger cubic
The fan-out found the vars an event wrote from a per-var map that left out vars with no synced sibling, so an unsynced write could overwrite a synced var written in the same event. Group the vars by storage name and find the written vars in each group, so a written var always keeps its value.
There was a problem hiding this comment.
All reported issues were addressed across 2 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
View guided diff | Re-trigger cubic
The groups came from a walk over a set of state classes, so their order, and the value that conflicting writes give the other synced vars, could differ between processes. Sort each group once when it is built.
Fixes #7567
All Submissions:
Type of change
New Feature Submission:
Changes To Core Features:
What
Several
rx.LocalStorage(..., sync=True)vars can share one storagename. A typical case is a named synced field on anrx.ComponentStatethat a page uses more than once. When the backend writes one of them, the frontend updateslocalStorage. The browser raises thestorageevent in other tabs only. So the sibling vars in the writing tab stay stale until a reload.This fix sets the siblings on the backend. In
BaseState._get_resolved_delta,_sync_shared_storagefinds each localStorage var that this event made dirty. It then sets every other synced var with the same storage name to the same value. A var that the event wrote itself keeps its own value. This happens in the same locked event, before the delta is resolved. So the writing tab gets all siblings in one delta, and it sends no extra sync event._shared_storage_groupsgroups the vars by storage name once per state tree, and the groups are cached. Hydration replay (_replay_client_storage) skips the fan-out. The frontend does not change.Tests
tests/units/test_state.py::test_shared_storage_name_syncs_siblings: a write to one var sets the synced siblings with that name.tests/units/test_state.py::test_shared_storage_name_keeps_event_writes: when one event writes two vars with the same name (synced or not), each var keeps its own value.tests/units/test_state.py::test_shared_storage_name_conflicting_writes_pick_by_name: when one event writes different values to one name, the other synced vars take the first written value in state and var name order, in every process.test_synced_storage_shared_name_syncs_siblings_in_writing_tab(Playwright): the siblings update in the writing tab, and the tab sends noupdate_vars_internal.test_synced_storage_shared_name_override_keeps_syncing(Playwright): aget_deltaoverride that rewrites the value does not stop later syncs.The first unit test and both Playwright tests fail on
mainand pass with the fix. All 42 tests intest_hydration_storage.pypass, including the race tests that hold socket replies.