Skip to content

Commit ca93158

Browse files
committed
unpack
1 parent 9f080b5 commit ca93158

File tree

5 files changed

+58
-31
lines changed

5 files changed

+58
-31
lines changed

reflex/app.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1759,7 +1759,7 @@ async def process(
17591759
})
17601760
# Get the state for the session exclusively.
17611761
async with app.state_manager.modify_state(
1762-
event.substate_token, context=event
1762+
event.substate_token, event=event
17631763
) as state:
17641764
# When this is a brand new instance of the state, signal the
17651765
# frontend to reload before processing it.

reflex/istate/manager/__init__.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
import dataclasses
55
from abc import ABC, abstractmethod
66
from collections.abc import AsyncIterator
7+
from typing import TypedDict
8+
9+
from typing_extensions import ReadOnly, Unpack
710

811
from reflex import constants
912
from reflex.config import get_config
@@ -13,6 +16,15 @@
1316
from reflex.utils.exceptions import InvalidStateManagerModeError
1417

1518

19+
class StateModificationContext(TypedDict, total=False):
20+
"""The context for modifying state."""
21+
22+
event: ReadOnly[Event]
23+
24+
25+
EmptyContext = StateModificationContext()
26+
27+
1628
@dataclasses.dataclass
1729
class StateManager(ABC):
1830
"""A class to manage many client states."""
@@ -73,26 +85,29 @@ async def get_state(self, token: str) -> BaseState:
7385

7486
@abstractmethod
7587
async def set_state(
76-
self, token: str, state: BaseState, *, context: Event | None = None
88+
self,
89+
token: str,
90+
state: BaseState,
91+
**context: Unpack[StateModificationContext],
7792
):
7893
"""Set the state for a token.
7994
8095
Args:
8196
token: The token to set the state for.
8297
state: The state to set.
83-
context: The event context.
98+
context: The state modification context.
8499
"""
85100

86101
@abstractmethod
87102
@contextlib.asynccontextmanager
88103
async def modify_state(
89-
self, token: str, *, context: Event | None = None
104+
self, token: str, **context: Unpack[StateModificationContext]
90105
) -> AsyncIterator[BaseState]:
91106
"""Modify the state for a token while holding exclusive lock.
92107
93108
Args:
94109
token: The token to modify the state for.
95-
context: The event context.
110+
context: The state modification context.
96111
97112
Yields:
98113
The state for the token.

reflex/istate/manager/disk.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@
99
from hashlib import md5
1010
from pathlib import Path
1111

12-
from typing_extensions import override
12+
from typing_extensions import Unpack, override
1313

1414
from reflex.environment import environment
15-
from reflex.event import Event
16-
from reflex.istate.manager import StateManager, _default_token_expiration
15+
from reflex.istate.manager import (
16+
StateManager,
17+
StateModificationContext,
18+
_default_token_expiration,
19+
)
1720
from reflex.state import BaseState, _split_substate_key, _substate_key
1821
from reflex.utils import console, path_ops, prerequisites
1922
from reflex.utils.misc import run_in_thread
@@ -303,14 +306,14 @@ async def _schedule_process_write_queue(self):
303306

304307
@override
305308
async def set_state(
306-
self, token: str, state: BaseState, *, context: Event | None = None
309+
self, token: str, state: BaseState, **context: Unpack[StateModificationContext]
307310
):
308311
"""Set the state for a token.
309312
310313
Args:
311314
token: The token to set the state for.
312315
state: The state to set.
313-
context: The event context.
316+
context: The state modification context.
314317
"""
315318
client_token, _ = _split_substate_key(token)
316319
if self._write_debounce_seconds > 0:
@@ -330,13 +333,13 @@ async def set_state(
330333
@override
331334
@contextlib.asynccontextmanager
332335
async def modify_state(
333-
self, token: str, *, context: Event | None = None
336+
self, token: str, **context: Unpack[StateModificationContext]
334337
) -> AsyncIterator[BaseState]:
335338
"""Modify the state for a token while holding exclusive lock.
336339
337340
Args:
338341
token: The token to modify the state for.
339-
context: The event context.
342+
context: The state modification context.
340343
341344
Yields:
342345
The state for the token.
@@ -351,7 +354,7 @@ async def modify_state(
351354
async with self._states_locks[client_token]:
352355
state = await self.get_state(token)
353356
yield state
354-
await self.set_state(token, state, context=context)
357+
await self.set_state(token, state, **context)
355358

356359
async def close(self):
357360
"""Close the state manager, flushing any pending writes to disk."""

reflex/istate/manager/memory.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@
55
import dataclasses
66
from collections.abc import AsyncIterator
77

8-
from typing_extensions import override
8+
from typing_extensions import Unpack, override
99

10-
from reflex.event import Event
11-
from reflex.istate.manager import StateManager
10+
from reflex.istate.manager import StateManager, StateModificationContext
1211
from reflex.state import BaseState, _split_substate_key
1312

1413

@@ -45,28 +44,31 @@ async def get_state(self, token: str) -> BaseState:
4544

4645
@override
4746
async def set_state(
48-
self, token: str, state: BaseState, *, context: Event | None = None
47+
self,
48+
token: str,
49+
state: BaseState,
50+
**context: Unpack[StateModificationContext],
4951
):
5052
"""Set the state for a token.
5153
5254
Args:
5355
token: The token to set the state for.
5456
state: The state to set.
55-
context: The event context.
57+
context: The state modification context.
5658
"""
5759
token = _split_substate_key(token)[0]
5860
self.states[token] = state
5961

6062
@override
6163
@contextlib.asynccontextmanager
6264
async def modify_state(
63-
self, token: str, *, context: Event | None = None
65+
self, token: str, **context: Unpack[StateModificationContext]
6466
) -> AsyncIterator[BaseState]:
6567
"""Modify the state for a token while holding exclusive lock.
6668
6769
Args:
6870
token: The token to modify the state for.
69-
context: The event context.
71+
context: The state modification context.
7072
7173
Yields:
7274
The state for the token.

reflex/istate/manager/redis.py

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,15 @@
1010
from redis import ResponseError
1111
from redis.asyncio import Redis
1212
from redis.asyncio.client import PubSub
13-
from typing_extensions import override
13+
from typing_extensions import Unpack, override
1414

1515
from reflex.config import get_config
1616
from reflex.environment import environment
17-
from reflex.event import Event
18-
from reflex.istate.manager import StateManager, _default_token_expiration
17+
from reflex.istate.manager import (
18+
StateManager,
19+
StateModificationContext,
20+
_default_token_expiration,
21+
)
1922
from reflex.state import BaseState, _split_substate_key, _substate_key
2023
from reflex.utils import console
2124
from reflex.utils.exceptions import (
@@ -264,7 +267,7 @@ async def set_state(
264267
state: BaseState,
265268
*,
266269
lock_id: bytes | None = None,
267-
context: Event | None = None,
270+
**context: Unpack[StateModificationContext],
268271
):
269272
"""Set the state for a token.
270273
@@ -287,7 +290,11 @@ async def set_state(
287290
f"Lock expired for token {token} while processing. Consider increasing "
288291
f"`app.state_manager.lock_expiration` (currently {self.lock_expiration}) "
289292
"or use `@rx.event(background=True)` decorator for long-running tasks."
290-
+ (f" Happened in event: {context.name}" if context is not None else "")
293+
+ (
294+
f" Happened in event: {event.name}"
295+
if (event := context.get("event")) is not None
296+
else ""
297+
)
291298
)
292299
raise LockExpiredError(msg)
293300
if lock_id is not None:
@@ -299,8 +306,8 @@ async def set_state(
299306
f"Lock for token {token} was held too long {time_taken=}s, "
300307
f"use `@rx.event(background=True)` decorator for long-running tasks."
301308
+ (
302-
f" Happened in event: {context.name}"
303-
if context is not None
309+
f" Happened in event: {event.name}"
310+
if (event := context.get("event")) is not None
304311
else ""
305312
),
306313
dedupe=True,
@@ -319,7 +326,7 @@ async def set_state(
319326
_substate_key(client_token, substate),
320327
substate,
321328
lock_id=lock_id,
322-
context=context,
329+
**context,
323330
),
324331
name=f"reflex_set_state|{client_token}|{substate.get_full_name()}",
325332
)
@@ -342,21 +349,21 @@ async def set_state(
342349
@override
343350
@contextlib.asynccontextmanager
344351
async def modify_state(
345-
self, token: str, *, context: Event | None = None
352+
self, token: str, **context: Unpack[StateModificationContext]
346353
) -> AsyncIterator[BaseState]:
347354
"""Modify the state for a token while holding exclusive lock.
348355
349356
Args:
350357
token: The token to modify the state for.
351-
context: The event context.
358+
context: The state modification context.
352359
353360
Yields:
354361
The state for the token.
355362
"""
356363
async with self._lock(token) as lock_id:
357364
state = await self.get_state(token)
358365
yield state
359-
await self.set_state(token, state, lock_id=lock_id, context=context)
366+
await self.set_state(token, state, lock_id=lock_id, **context)
360367

361368
@staticmethod
362369
def _lock_key(token: str) -> bytes:

0 commit comments

Comments
 (0)