Skip to content

Commit 5c6b33a

Browse files
committed
Remove token/sid associations when server is exiting
This allows existing tokens to reconnect to redis after a hot or cold reload of the app. Otherwise, the old associations for the token remain in place and when the same client reconnects, it is given a new_token, since the requested token is already "taken" in redis.
1 parent 4468e14 commit 5c6b33a

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

reflex/app_mixins/lifespan.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,17 @@ async def _run_lifespan_tasks(self, app: Starlette):
6060
for task in running_tasks:
6161
console.debug(f"Canceling lifespan task: {task}")
6262
task.cancel(msg="lifespan_cleanup")
63+
# Disassociate sid / token pairings so they can be reconnected properly.
64+
try:
65+
event_namespace = self.event_namespace # pyright: ignore[reportAttributeAccessIssue]
66+
except AttributeError:
67+
pass
68+
else:
69+
try:
70+
if event_namespace:
71+
await event_namespace._token_manager.disconnect_all()
72+
except Exception as e:
73+
console.error(f"Error during lifespan cleanup: {e}")
6374

6475
def register_lifespan_task(self, task: Callable | asyncio.Task, **task_kwargs):
6576
"""Register a task to run during the lifespan of the app.

reflex/utils/token_manager.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,16 @@ def create(cls) -> TokenManager:
6666

6767
return LocalTokenManager()
6868

69+
async def disconnect_all(self):
70+
"""Disconnect all tracked tokens when the server is going down."""
71+
token_sid_pairs: set[tuple[str, str]] = set(self.token_to_sid.items())
72+
token_sid_pairs.update(
73+
((token, sid) for sid, token in self.sid_to_token.items())
74+
)
75+
# Perform the disconnection logic here
76+
for token, sid in token_sid_pairs:
77+
await self.disconnect_token(token, sid)
78+
6979

7080
class LocalTokenManager(TokenManager):
7181
"""Token manager using local in-memory dictionaries (single worker)."""

0 commit comments

Comments
 (0)