Auto-recreate connection on loop change #2098
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixed issue that forced you to implement hacks and use session scoped fixtures in tests
Now we automatically recreate pool on loop change, which is not a problem for tests. For prod we issue warning in such case, as it indicates that something has gone wrong
AI Summary:
This pull request introduces robust handling for event loop changes in database connections, especially relevant for async backends that bind connection pools to the event loop at creation time. Now, if a connection is accessed from a different event loop than it was created on, Tortoise will automatically recreate the connection and emit a warning. This behavior is documented, tested, and can be suppressed as needed (especially in test environments). The changes also add a dedicated warning class and update backend clients to track their bound event loop.
Event Loop Handling and Connection Safety:
Added a
_bound_loopattribute and_check_loop/_post_connectmethods toBaseDBAsyncClientand all backend clients (e.g., asyncpg, aiomysql, sqlite, psycopg, odbc). These ensure each connection knows which event loop it was created on and can verify loop consistency. (tortoise/backends/base/client.py[1] [2];tortoise/backends/asyncpg/client.py[3];tortoise/backends/mysql/client.py[4];tortoise/backends/odbc/client.py[5];tortoise/backends/psycopg/client.py[6];tortoise/backends/sqlite/client.py[7]Modified
ConnectionHandler.get()to check for event loop changes using_check_loop(). If a change is detected, a new connection is transparently created, and aTortoiseLoopSwitchWarningis emitted. This prevents subtle bugs when test frameworks or application code switch event loops. (tortoise/connection.py[1] [2]Testing and Warning Suppression:
Added comprehensive tests for event loop validation and reconnection logic, ensuring that connections are properly recreated and warnings are emitted or suppressed as appropriate. (
tests/test_connection.py[1] [2] [3] [4];tests/test_query_api.py[5]Updated
tortoise_test_context()to automatically suppressTortoiseLoopSwitchWarningin test environments, simplifying test setup. (tortoise/context.pytortoise/context.pyR576-R581)Documentation and Developer Guidance:
docs/connections.rst[1];docs/contrib/unittest.rst[2]Warnings and Developer Experience:
TortoiseLoopSwitchWarning, a dedicated warning class with clear docstrings and usage guidance, to help developers identify and address event loop issues. (tortoise/warnings.pytortoise/warnings.pyR1-R18)Overall, these changes make Tortoise ORM safer and more predictable in async environments, especially when dealing with test frameworks or mixed sync/async code.