]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Improved usage of ``asyncio.shield()``
authorFederico Caselli <cfederico87@gmail.com>
Tue, 13 Sep 2022 19:23:12 +0000 (21:23 +0200)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 15 Sep 2022 13:05:30 +0000 (09:05 -0400)
Fixes: #8516
Change-Id: Ifd8f5e5f42d9fbcd5b8d00bddc81ff6be690a75e
(cherry picked from commit e2e85de93daef31c75d397251cee2fbee7a5de65)

doc/build/changelog/unreleased_14/8516.rst [new file with mode: 0644]
lib/sqlalchemy/ext/asyncio/base.py
lib/sqlalchemy/ext/asyncio/engine.py
lib/sqlalchemy/ext/asyncio/session.py

diff --git a/doc/build/changelog/unreleased_14/8516.rst b/doc/build/changelog/unreleased_14/8516.rst
new file mode 100644 (file)
index 0000000..2f83586
--- /dev/null
@@ -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.
index 3f77f55007e6a6402552badfddb06803a23be14d..ae100ecf5f0ab29e24f33e897818ac936cdce5bd 100644 (file)
@@ -1,3 +1,9 @@
+# ext/asyncio/base.py
+# Copyright (C) 2020-2022 the SQLAlchemy authors and contributors
+# <see AUTHORS file>
+#
+# This module is part of SQLAlchemy and is released under
+# the MIT License: https://www.opensource.org/licenses/mit-license.php
 import abc
 import functools
 import weakref
index 4fbe4f7a592cc0fac0469dab7d0ef9842fc658e0..5bfda1507049143d0242e60bfa049aa6a4d3b9fb 100644 (file)
@@ -551,7 +551,8 @@ class AsyncConnection(ProxyComparable, StartableContext, AsyncConnectable):
         return self.start().__await__()
 
     async def __aexit__(self, type_, value, traceback):
-        await asyncio.shield(self.close())
+        task = asyncio.create_task(self.close())
+        await asyncio.shield(task)
 
 
 @util.create_proxy_methods(
@@ -606,7 +607,8 @@ class AsyncEngine(ProxyComparable, 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):
         if not sync_engine.dialect.is_async:
index 378cbcbf2f8e4c0f93b99fc4b180026e065035de..7346840579cacd5bb0d16b1e50ce97d46ccb2927 100644 (file)
@@ -4,7 +4,6 @@
 #
 # This module is part of SQLAlchemy and is released under
 # the MIT License: https://www.opensource.org/licenses/mit-license.php
-
 import asyncio
 
 from . import engine
@@ -628,7 +627,8 @@ class AsyncSession(ReversibleProxy):
         return self
 
     async def __aexit__(self, type_, value, traceback):
-        await asyncio.shield(self.close())
+        task = asyncio.create_task(self.close())
+        await asyncio.shield(task)
 
     def _maker_context_manager(self):
         # no @contextlib.asynccontextmanager until python3.7, gr
@@ -649,7 +649,8 @@ class _AsyncSessionContextManager:
             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(ReversibleProxy, StartableContext):