Skip to content

Commit c0fccfb

Browse files
committed
fix
1 parent 4c32f95 commit c0fccfb

File tree

4 files changed

+11
-80
lines changed

4 files changed

+11
-80
lines changed

reflex/app.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2140,12 +2140,3 @@ async def link_token_to_sid(self, sid: str, token: str):
21402140
if new_token:
21412141
# Duplicate detected, emit new token to client
21422142
await self.emit("new_token", new_token, to=sid)
2143-
2144-
async def close(self) -> None:
2145-
"""Close any resources used by the event namespace.
2146-
2147-
This is necessary in testing scenarios to close between asyncio test cases
2148-
to avoid having lingering connections associated with event loops.
2149-
"""
2150-
if hasattr(self, "_token_manager"):
2151-
await self._token_manager.close()

reflex/testing.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -313,15 +313,6 @@ async def _shutdown(*args, **kwargs) -> None:
313313
with contextlib.suppress(ValueError):
314314
await self.app_instance._state_manager.close()
315315

316-
# ensure token manager redis connections are closed
317-
if (
318-
self.app_instance is not None
319-
and hasattr(self.app_instance, "event_namespace")
320-
and self.app_instance.event_namespace is not None
321-
):
322-
with contextlib.suppress(Exception):
323-
await self.app_instance.event_namespace.close()
324-
325316
# socketio shutdown handler
326317
if self.app_instance is not None and self.app_instance.sio is not None:
327318
with contextlib.suppress(TypeError):
@@ -385,6 +376,17 @@ async def _reset_backend_state_manager(self):
385376
msg = "Failed to reset state manager."
386377
raise RuntimeError(msg)
387378

379+
# Also reset the TokenManager to avoid loop affinity issues
380+
if (
381+
hasattr(self.app_instance, "event_namespace")
382+
and self.app_instance.event_namespace is not None
383+
and hasattr(self.app_instance.event_namespace, "_token_manager")
384+
):
385+
# Import here to avoid circular imports
386+
from reflex.utils.token_manager import TokenManager
387+
388+
self.app_instance.event_namespace._token_manager = TokenManager.create()
389+
388390
def _start_frontend(self):
389391
# Set up the frontend.
390392
with chdir(self.app_path):

reflex/utils/token_manager.py

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,6 @@ async def disconnect_token(self, token: str, sid: str) -> None:
5252
sid: The Socket.IO session ID.
5353
"""
5454

55-
@abstractmethod
56-
async def close(self) -> None:
57-
"""Close any resources used by the token manager.
58-
59-
Subclasses must implement this method.
60-
"""
61-
6255
@classmethod
6356
def create(cls) -> TokenManager:
6457
"""Factory method to create appropriate TokenManager implementation.
@@ -114,13 +107,6 @@ async def disconnect_token(self, token: str, sid: str) -> None:
114107
self.token_to_sid.pop(token, None)
115108
self.sid_to_token.pop(sid, None)
116109

117-
async def close(self) -> None:
118-
"""Close any resources used by the token manager.
119-
120-
LocalTokenManager has no resources to close.
121-
"""
122-
# No resources to clean up for local manager
123-
124110

125111
class RedisTokenManager(LocalTokenManager):
126112
"""Token manager using Redis for distributed multi-worker support.
@@ -229,17 +215,3 @@ async def disconnect_token(self, token: str, sid: str) -> None:
229215

230216
# Clean up local dicts (always do this)
231217
await super().disconnect_token(token, sid)
232-
233-
async def close(self) -> None:
234-
"""Close Redis connection to prevent closed loop errors in tests.
235-
236-
It is necessary in testing scenarios to close between asyncio test cases
237-
to avoid having lingering redis connections associated with event loops
238-
that will be closed (each test case uses its own event loop).
239-
240-
Note: Connections will be automatically reopened when needed.
241-
"""
242-
try:
243-
await self.redis.aclose(close_connection_pool=True)
244-
except Exception as e:
245-
console.error(f"Redis close error: {e}")

tests/units/utils/test_token_manager.py

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -174,15 +174,6 @@ async def test_disconnect_nonexistent_token(self, manager):
174174
assert len(manager.token_to_sid) == 0
175175
assert len(manager.sid_to_token) == 0
176176

177-
async def test_close_does_nothing(self, manager):
178-
"""Test close method does nothing for LocalTokenManager.
179-
180-
Args:
181-
manager: LocalTokenManager fixture instance.
182-
"""
183-
await manager.close()
184-
# Should not raise any errors
185-
186177

187178
class TestRedisTokenManager:
188179
"""Tests for RedisTokenManager."""
@@ -411,28 +402,3 @@ def test_inheritance_from_local_manager(self, manager):
411402
assert isinstance(manager, LocalTokenManager)
412403
assert hasattr(manager, "token_to_sid")
413404
assert hasattr(manager, "sid_to_token")
414-
415-
async def test_close_calls_redis_aclose(self, manager, mock_redis):
416-
"""Test close method calls Redis aclose with proper parameters.
417-
418-
Args:
419-
manager: RedisTokenManager fixture instance.
420-
mock_redis: Mock Redis client fixture.
421-
"""
422-
await manager.close()
423-
424-
mock_redis.aclose.assert_called_once_with(close_connection_pool=True)
425-
426-
async def test_close_handles_redis_error(self, manager, mock_redis):
427-
"""Test close method handles Redis errors gracefully.
428-
429-
Args:
430-
manager: RedisTokenManager fixture instance.
431-
mock_redis: Mock Redis client fixture.
432-
"""
433-
mock_redis.aclose.side_effect = Exception("Redis close error")
434-
435-
# Should not raise an error
436-
await manager.close()
437-
438-
mock_redis.aclose.assert_called_once_with(close_connection_pool=True)

0 commit comments

Comments
 (0)