From 433f2dd562bc4136c5230e0f8ef09077af87c898 Mon Sep 17 00:00:00 2001 From: Stepan Burlakov Date: Fri, 3 Dec 2021 16:27:57 +0200 Subject: [PATCH 1/3] add custom loop for connection __del__ --- src/firebolt/db/connection.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/firebolt/db/connection.py b/src/firebolt/db/connection.py index 1a54aa10df2..a56562d5513 100644 --- a/src/firebolt/db/connection.py +++ b/src/firebolt/db/connection.py @@ -1,5 +1,6 @@ from __future__ import annotations +from asyncio import new_event_loop from functools import wraps from inspect import cleandoc from types import TracebackType @@ -37,7 +38,7 @@ class Connection(AsyncBaseConnection): """ ) - __slots__ = AsyncBaseConnection.__slots__ + ("_closing_lock",) + __slots__ = AsyncBaseConnection.__slots__ + ("_closing_lock", "_loop") cursor_class = Cursor @@ -46,6 +47,7 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: # Holding this lock for write means that connection is closing itself. # cursor() should hold this lock for read to read/write state self._closing_lock = RWLockWrite() + self._loop = new_event_loop() @wraps(AsyncBaseConnection.cursor) def cursor(self) -> Cursor: @@ -57,7 +59,7 @@ def cursor(self) -> Cursor: @wraps(AsyncBaseConnection._aclose) def close(self) -> None: with self._closing_lock.gen_wlock(): - return async_to_sync(super()._aclose)() + return self._loop.run_until_complete(self._aclose()) # Context manager support def __enter__(self) -> Connection: From 5362fabc3bb69815abce18d84b8df4215adabffe Mon Sep 17 00:00:00 2001 From: Stepan Burlakov Date: Mon, 6 Dec 2021 11:40:38 +0200 Subject: [PATCH 2/3] close connection loop in the end --- src/firebolt/db/connection.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/firebolt/db/connection.py b/src/firebolt/db/connection.py index a56562d5513..f5a6ef37cbd 100644 --- a/src/firebolt/db/connection.py +++ b/src/firebolt/db/connection.py @@ -59,7 +59,8 @@ def cursor(self) -> Cursor: @wraps(AsyncBaseConnection._aclose) def close(self) -> None: with self._closing_lock.gen_wlock(): - return self._loop.run_until_complete(self._aclose()) + self._loop.run_until_complete(self._aclose()) + self._loop.close() # Context manager support def __enter__(self) -> Connection: From a093061340668689302231829f0d1556962003c9 Mon Sep 17 00:00:00 2001 From: Stepan Burlakov Date: Mon, 6 Dec 2021 11:48:21 +0200 Subject: [PATCH 3/3] don't close connection twice --- src/firebolt/db/connection.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/firebolt/db/connection.py b/src/firebolt/db/connection.py index f5a6ef37cbd..c9e8342a5c7 100644 --- a/src/firebolt/db/connection.py +++ b/src/firebolt/db/connection.py @@ -59,8 +59,9 @@ def cursor(self) -> Cursor: @wraps(AsyncBaseConnection._aclose) def close(self) -> None: with self._closing_lock.gen_wlock(): - self._loop.run_until_complete(self._aclose()) - self._loop.close() + if not self.closed: + self._loop.run_until_complete(self._aclose()) + self._loop.close() # Context manager support def __enter__(self) -> Connection: