Skip to content

Fix state manager lock isolation - #6830

Merged
masenf merged 5 commits into
reflex-dev:mainfrom
harsh21234i:fix/state-manager-lock-factory
Aug 10, 2026
Merged

Fix state manager lock isolation#6830
masenf merged 5 commits into
reflex-dev:mainfrom
harsh21234i:fix/state-manager-lock-factory

Conversation

@harsh21234i

@harsh21234i harsh21234i commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #6829.

This changes backend state manager internals so each manager instance owns its own _state_manager_lock instead of sharing a lock created at class-definition time.

Updated managers:

  • StateManagerMemory
  • StateManagerDisk
  • StateManagerRedis

Redis was included because it had the same dataclasses.field(default=asyncio.Lock()) pattern as memory and disk.

Root cause

asyncio.Lock() was evaluated when the dataclass field was defined, so every instance of the same manager class received the same lock object.

Using default_factory=asyncio.Lock creates a fresh lock per manager instance.

The PR also corrects an existing unit-test assertion whose comment already said separate state-manager instances should not share locks, but whose assertion checked the opposite.

Validation

uv run pytest tests/units/test_state.py::test_state_manager_modify_state tests/units/istate/manager/test_manager_locks.py -q

Result: 6 passed.

uv run pytest tests/units --cov --no-cov-on-fail --cov-report=

Result: 6955 passed, 18 skipped.

uv run towncrier check --config pyproject.toml --dir . --compare-with upstream/main

Result: found news/6830.bugfix.md.

uv run pre-commit run --files reflex/istate/manager/memory.py reflex/istate/manager/disk.py reflex/istate/manager/redis.py tests/units/istate/manager/test_manager_locks.py tests/units/test_state.py news/6830.bugfix.md

Result: passed.

@greptile-apps

greptile-apps Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR gives each memory, disk, and Redis state-manager instance its own internal lock and updates tests to enforce lock isolation.

  • Replaces class-definition-time asyncio.Lock() defaults with default_factory=asyncio.Lock.
  • Adds lock-isolation coverage for all three state-manager implementations.
  • Corrects an existing assertion that contradicted its accompanying comment.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
reflex/istate/manager/memory.py Creates the manager lock per instance instead of sharing a class-definition-time default.
reflex/istate/manager/disk.py Creates the disk manager lock per instance while preserving the existing locking structure.
reflex/istate/manager/redis.py Uses a per-instance lock factory while retaining the field's non-init semantics.
tests/units/istate/manager/test_manager_locks.py Adds focused identity checks confirming lock isolation across memory, disk, and Redis manager instances.
tests/units/test_state.py Corrects the existing lock assertion to match the intended per-instance isolation contract.

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

@codspeed-hq

codspeed-hq Bot commented Aug 1, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 26 untouched benchmarks
⏩ 8 skipped benchmarks1


Comparing harsh21234i:fix/state-manager-lock-factory (25b4e35) 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.

@harsh21234i
harsh21234i marked this pull request as ready for review August 1, 2026 06:59
@harsh21234i
harsh21234i requested a review from a team as a code owner August 1, 2026 06:59
@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.

@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 4 files

Re-trigger cubic

@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.

1 issue found and verified against the latest diff

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="tests/units/istate/manager/test_manager_locks.py">

<violation number="1" location="tests/units/istate/manager/test_manager_locks.py:25">
P3: Instantiating `StateManagerDisk()` in this lock-isolation test runs `__post_init__`, which creates the real app states directory and `_purge_expired_states()` deletes any stale `.pkl` files in it — filesystem side effects that the lock-isolation assertion doesn't need. If the test is run against a real states dir, it can delete state files. Consider isolating this (e.g., point `REFLEX_STATE_MANAGER_DISK_DEBOUNCE_SECONDS`/states dir at a tmp_path, or construct the object via `object.__new__`/`dataclasses` without `__post_init__`).</violation>
</file>

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

Comment thread tests/units/istate/manager/test_manager_locks.py Outdated

@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 6 files

Re-trigger cubic

@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 6 files

Re-trigger cubic

@masenf
masenf merged commit 0134175 into reflex-dev:main Aug 10, 2026
108 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.

StateManagerMemory and StateManagerDisk share one asyncio lock across instances

2 participants