From 939f77c94b4e47ea611672a85047b61ab7e3590b Mon Sep 17 00:00:00 2001 From: Federico Caselli Date: Tue, 13 Sep 2022 21:23:12 +0200 Subject: [PATCH] Improved usage of ``asyncio.shield()`` Fixes: #8516 Change-Id: Ifd8f5e5f42d9fbcd5b8d00bddc81ff6be690a75e --- doc/build/changelog/unreleased_14/8516.rst | 9 +++++++++ lib/sqlalchemy/ext/asyncio/engine.py | 6 ++++-- lib/sqlalchemy/ext/asyncio/session.py | 6 ++++-- 3 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 doc/build/changelog/unreleased_14/8516.rst diff --git a/doc/build/changelog/unreleased_14/8516.rst b/doc/build/changelog/unreleased_14/8516.rst new file mode 100644 index 0000000000..2f83586e2a --- /dev/null +++ b/doc/build/changelog/unreleased_14/8516.rst @@ -0,0 +1,9 @@ +.. change:: + :tags: bug, asyncio + :tickets: 8516 + + Improved implementation of ``asyncio.shield()`` used in context managers as + added in :ticket:`8145`, such that the "close" operation is enclosed within + an ``asyncio.Task`` which is then strongly referenced as the operation + proceeds. This is per Python documentation indicating that the task is + otherwise not strongly referenced. diff --git a/lib/sqlalchemy/ext/asyncio/engine.py b/lib/sqlalchemy/ext/asyncio/engine.py index e8ac10a3d0..4d0c872b30 100644 --- a/lib/sqlalchemy/ext/asyncio/engine.py +++ b/lib/sqlalchemy/ext/asyncio/engine.py @@ -694,7 +694,8 @@ class AsyncConnection( return self.start().__await__() async def __aexit__(self, type_: Any, value: Any, traceback: Any) -> None: - await asyncio.shield(self.close()) + task = asyncio.create_task(self.close()) + await asyncio.shield(task) # START PROXY METHODS AsyncConnection @@ -860,7 +861,8 @@ class AsyncEngine(ProxyComparable[Engine], AsyncConnectable): await self.transaction.__aexit__(type_, value, traceback) await self.conn.close() - await asyncio.shield(go()) + task = asyncio.create_task(go()) + await asyncio.shield(task) def __init__(self, sync_engine: Engine): if not sync_engine.dialect.is_async: diff --git a/lib/sqlalchemy/ext/asyncio/session.py b/lib/sqlalchemy/ext/asyncio/session.py index d4b6b6d50a..60b77f3ea6 100644 --- a/lib/sqlalchemy/ext/asyncio/session.py +++ b/lib/sqlalchemy/ext/asyncio/session.py @@ -851,7 +851,8 @@ class AsyncSession(ReversibleProxy[Session]): return self async def __aexit__(self, type_: Any, value: Any, traceback: Any) -> None: - await asyncio.shield(self.close()) + task = asyncio.create_task(self.close()) + await asyncio.shield(task) def _maker_context_manager(self: _AS) -> _AsyncSessionContextManager[_AS]: return _AsyncSessionContextManager(self) @@ -1516,7 +1517,8 @@ class _AsyncSessionContextManager(Generic[_AS]): await self.trans.__aexit__(type_, value, traceback) await self.async_session.__aexit__(type_, value, traceback) - await asyncio.shield(go()) + task = asyncio.create_task(go()) + await asyncio.shield(task) class AsyncSessionTransaction( -- 2.47.2