Skip to content

fix: recompute cached vars after a hot reload - #7616

Open
ShaanGS wants to merge 2 commits into
reflex-dev:mainfrom
ShaanGS:fix-cached-var-hot-reload
Open

ShaanGS wants to merge 2 commits into
reflex-dev:mainfrom
ShaanGS:fix-cached-var-hot-reload

Conversation

@ShaanGS

@ShaanGS ShaanGS commented Oct 20, 2026 •

Copy link
Copy Markdown

All Submissions:

  • Have you followed the guidelines stated in CONTRIBUTING.md file?
  • Have you checked to ensure there aren't any other open Pull Requests for the desired changed?

Type of change

  • Bug fix (non-breaking change which fixes an issue)

Changes To Core Features:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your core changes, as applicable?
  • Have you successfully ran tests with your changes locally?

Description

reflex run keeps states on disk so they survive a hot reload, and the saved state includes the values of cached vars. When a reload only changes a getter, the schema still matches, so the old value comes back and the page keeps showing it.

StateManagerDisk only reads a state from disk when it isn't in memory, which in practice means the backend just restarted. It now drops the cached computed var values of the states it reads from disk and keeps their fields. States served from memory keep their cache, and _deserialize is unchanged, so Redis, which reads states on every event, caches as before. That also means your probe in the issue, which calls _deserialize directly, still prints the cached value.

Tests (both fail without the fix, showing the old two-row value):

  • test_states_from_disk_recompute_cached_vars: a state and a substate saved by one manager are read by a new one. Fields are kept, cached vars are recomputed, and a read from memory still uses the cache.
  • test_hot_reload_recomputes_cached_vars: the issue's app in two real processes, editing only the getter in between.

I also tried the real dev server with the issue's app. After editing the getter, main still showed 2 rows after the reload and after a full page refresh, and this branch shows 1 row. A counter I had incremented kept its value both times. I didn't add a browser test because AppHarness runs the backend in-process, so it can't reload into a new process.

This doesn't cover Redis in dev mode, where every event reads the state from Redis. Telling a reload apart there would need something extra, like recording which process saved the state. Happy to add that here or in a follow-up if you want it.

closes #3989

View guided diff

The disk state manager only reads a state from disk when it is not in
memory, which in practice means the backend restarted, as on a hot
reload. The saved state still held the values of cached vars, so a
reload that only changed a getter kept showing the old value.

Drop the cached computed var values of states read from disk and keep
their fields. States served from memory keep their cache.
@ShaanGS
ShaanGS requested a review from a team as a code owner October 20, 2026 13:33

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues found across 3 files

View guided diff | Re-trigger cubic

@greptile-apps

greptile-apps Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge, with the previous finding fully addressed.

Summary

The PR clears cached computed values when loading saved states from disk, while keeping state fields and in-memory caches.

  • Disk-restored states recompute cached values after a backend restart.

Reviews (2) · Last reviewed commit: "test: add a docstring to the subprocess ..." · Reviewed by Greptile

Comment thread tests/units/istate/manager/test_disk.py

This branch has not been deployed

No deployments
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.

Cached var are not busted on hot reload

1 participant