fix: recompute cached vars after a hot reload
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