Skip to content

Fix disk state manager debounced writes - #6807

Open
harsh21234i wants to merge 4 commits into
reflex-dev:mainfrom
harsh21234i:fix/disk-state-manager-debounced-writes
Open

Fix disk state manager debounced writes#6807
harsh21234i wants to merge 4 commits into
reflex-dev:mainfrom
harsh21234i:fix/disk-state-manager-debounced-writes

Conversation

@harsh21234i

@harsh21234i harsh21234i commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Fixes #6806

Summary

Fixes a disk state manager bug where debounced set_state() calls for non-BaseState tokens could return stale in-
memory values and flush the wrong value to disk.

Problem

When StateManagerDisk used _write_debounce_seconds > 0, set_state() only queued the first value for a token. A
later set_state() before the debounce flush did not update the queued item, so close() or the background flush
could persist stale data.

Also, non-BaseState values were not updated in the in-memory cache while the write was pending, so get_state()
could return the default/old value before the disk flush completed.

Changes

  • Update the in-memory cache immediately for non-BaseState tokens.
  • Replace existing queued write payloads with the latest value.
  • Preserve the original queue timestamp so repeated updates do not indefinitely delay the flush.
  • Add regression tests for pending read-after-write behavior and latest-value flushing.

Testing

  • uv run pytest tests/units/test_state.py::test_state_manager_disk_debounced_set_state_updates_non_base_state_cache tests/units/test_state.py::test_state_manager_disk_debounced_set_state_flushes_latest_non_base_state -q
  • uv run pytest tests/units/test_state.py -k "deserialize_gc_state_disk or state_manager_disk_close_resets_write_queue_task or state_manager_disk_debounced_set_state" -q
  • uv run ruff check reflex/istate/manager/disk.py tests/units/test_state.py
  • uv run ruff format --check reflex/istate/manager/disk.py tests/units/test_state.py
  • uv run pyright reflex/istate/manager/disk.py tests/units/test_state.py

@harsh21234i
harsh21234i requested a review from a team as a code owner July 23, 2026 09:53
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@codspeed-hq

codspeed-hq Bot commented Jul 23, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 26 untouched benchmarks
⏩ 8 skipped benchmarks1


Comparing harsh21234i:fix/disk-state-manager-debounced-writes (cc39596) with main (346177c)2

Open in CodSpeed

Footnotes

  1. 8 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

  2. No successful run was found on main (d8a132b) during the generation of this report, so 346177c was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@greptile-apps

greptile-apps Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes two related bugs in StateManagerDisk.set_state around debounced writes for non-BaseState tokens: the in-memory cache was not updated while a write was pending (causing stale reads), and repeated set_state calls before the flush only retained the first-queued value (flushing stale data).

  • Debounce path: cache is now updated immediately for non-BaseState tokens, and the write-queue entry is always replaced with the latest state while preserving the original timestamp so the debounce deadline isn't pushed out by repeated updates.
  • Immediate path: cache update is now sequenced after set_state_for_substate succeeds, preventing a stale in-memory value when the disk write fails — accompanied by a new regression test (test_state_manager_disk_immediate_set_state_failure_keeps_previous_cache) that exercises this path.
  • Three new tests cover read-after-write visibility in debounce mode, latest-value flushing, and cache integrity on write failure.

Confidence Score: 5/5

  • The changes are narrowly scoped to set_state in the disk manager, fix clearly described bugs, and are backed by three new regression tests.
  • The logic is correct: StateToken.get_and_reset_touched_state always returns True so the optimistic debounce cache update is always matched by an eventual disk write; the immediate-path cache update is correctly sequenced after the write so a failed write leaves the cache consistent with disk. No regressions in the surrounding serialization or lock-management code were introduced.
  • No files require special attention.

Important Files Changed

Filename Overview
reflex/istate/manager/disk.py Two targeted fixes in set_state: optimistic in-memory cache update for non-BaseState tokens in the debounce path, and cache update moved to after a successful disk write in the immediate path. Logic is correct and consistent with the token type semantics (StateToken.get_and_reset_touched_state always returns True, so writes always happen).
tests/units/test_state.py Three new regression tests covering: read-after-write visibility in debounce mode, latest-value flushing with timestamp preservation, and cache integrity after failed immediate writes. All three exercise the code paths changed by the fix.
news/6807.bugfix.md Changelog entry describing the debounce fix.

Reviews (4): Last reviewed commit: "Merge branch 'main' into fix/disk-state-..." | Re-trigger Greptile

Comment thread reflex/istate/manager/disk.py
@harsh21234i

harsh21234i commented Jul 31, 2026

Copy link
Copy Markdown
Contributor Author

hey @masenf @FarhanAliRaza can you go through this?

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.

StateManagerDisk drops debounced set_state updates for non-BaseState tokens

1 participant