-
Notifications
You must be signed in to change notification settings - Fork 1.5k
split manager #5852
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
split manager #5852
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Greptile Overview
Summary
This PR implements a comprehensive refactoring that splits the monolithic state manager implementation into a modular architecture. The changes extract `StateManagerDisk`, `StateManagerMemory`, and `StateManagerRedis` from `reflex/state.py` into dedicated modules under `reflex/istate/manager/`.The refactoring introduces an abstract base class StateManager
with a factory method StateManager.create()
that automatically selects the appropriate backend based on configuration and Redis availability. The new structure creates three specialized modules: disk.py
for persistent file-based storage, memory.py
for in-memory state management, and redis.py
for distributed Redis-backed storage.
Key improvements include automatic Redis detection that overrides config settings, centralized expiration parameter handling, and utility functions for state management. The changes also fix a timing precision issue in Redis operations by switching from time.time()
to time.monotonic()
. All import statements across the codebase have been updated to reflect the new module structure, with state managers now imported from their dedicated modules while maintaining backward compatibility through the factory pattern.
Important Files Changed
Changed Files
Filename | Score | Overview |
---|---|---|
reflex/istate/manager/__init__.py |
4/5 | Introduces new modular state manager architecture with factory pattern and automatic Redis detection |
reflex/istate/manager/disk.py |
4/5 | New disk-based state manager with persistent storage using pickle serialization and MD5 hashing |
reflex/istate/manager/memory.py |
5/5 | Extracted in-memory state manager with identical functionality from original implementation |
reflex/istate/manager/redis.py |
4/5 | Extracted Redis state manager with timing precision fix using monotonic time |
reflex/state.py |
5/5 | Removes state manager imports from public API and moves to local imports where needed |
reflex/testing.py |
5/5 | Updates imports to use new modular state manager structure |
tests/units/test_state.py |
5/5 | Reorganizes imports and moves LockExpiredError to reflex.utils.exceptions |
tests/units/test_app.py |
5/5 | Updates import statements to reflect new state manager module organization |
tests/units/test_state_tree.py |
5/5 | Simple import path update for StateManagerRedis |
tests/integration/test_client_storage.py |
5/5 | Refactors imports to use dedicated state manager modules |
tests/integration/test_connection_banner.py |
5/5 | Updates import path for StateManagerRedis to new module location |
Confidence score: 4/5
- This PR is generally safe to merge but requires careful attention to the new factory pattern and automatic Redis detection logic
- Score reflects well-structured refactoring with comprehensive test updates, but complexity in the factory method and Redis auto-detection may need monitoring
- Pay close attention to
reflex/istate/manager/__init__.py
for the automatic Redis detection logic and factory method implementation
Sequence Diagram
sequenceDiagram
participant User
participant StateManager
participant Config
participant Prerequisites
participant StateManagerMemory
participant StateManagerDisk
participant StateManagerRedis
participant Redis
User->>StateManager: StateManager.create(state)
StateManager->>Config: get_config()
Config-->>StateManager: config
StateManager->>Prerequisites: parse_redis_url()
Prerequisites-->>StateManager: redis_url or None
alt redis_url exists
StateManager->>Config: set state_manager_mode = REDIS
end
alt config.state_manager_mode == MEMORY
StateManager->>StateManagerMemory: StateManagerMemory(state=state)
StateManagerMemory-->>StateManager: memory_manager
else config.state_manager_mode == DISK
StateManager->>StateManagerDisk: StateManagerDisk(state=state)
StateManagerDisk-->>StateManager: disk_manager
else config.state_manager_mode == REDIS
StateManager->>Prerequisites: get_redis()
Prerequisites-->>StateManager: redis_client
alt redis_client exists
StateManager->>StateManagerRedis: StateManagerRedis(state, redis, token_expiration, lock_expiration, lock_warning_threshold)
StateManagerRedis-->>StateManager: redis_manager
end
end
StateManager-->>User: state_manager_instance
User->>StateManager: get_state(token)
StateManager->>StateManagerRedis: get_state(token)
StateManagerRedis->>Redis: get(substate_key)
Redis-->>StateManagerRedis: serialized_state or None
alt serialized_state exists
StateManagerRedis->>StateManagerRedis: BaseState._deserialize(data)
else serialized_state is None
StateManagerRedis->>StateManagerRedis: create new state instance
end
StateManagerRedis-->>StateManager: state_instance
StateManager-->>User: state_instance
User->>StateManager: set_state(token, state)
StateManager->>StateManagerRedis: set_state(token, state, lock_id)
StateManagerRedis->>StateManagerRedis: state._serialize()
StateManagerRedis->>Redis: set(substate_key, serialized_state, ex=token_expiration)
Redis-->>StateManagerRedis: success
StateManagerRedis-->>StateManager: success
StateManager-->>User: success
11 files reviewed, 4 comments
CodSpeed Performance ReportMerging #5852 will not alter performanceComparing Summary
|
No description provided.