Skip to content

Commit e5e53ee

Browse files
chore: improve task and test cleanup (#277)
1 parent 8def64f commit e5e53ee

File tree

4 files changed

+34
-24
lines changed

4 files changed

+34
-24
lines changed

google/cloud/sql/connector/connector.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,23 @@ def connect(
150150
icm.force_refresh()
151151
raise (e)
152152

153+
async def _close(self) -> None:
154+
"""Helper function to close InstanceConnectionManagers' tasks."""
155+
await asyncio.gather(*[icm.close() for icm in self._instances.values()])
156+
157+
def __del__(self) -> None:
158+
"""Deconstructor to make sure InstanceConnectionManagers are closed
159+
and tasks have finished to have a graceful exit.
160+
"""
161+
logger.debug("Entering deconstructor")
162+
163+
deconstruct_future = asyncio.run_coroutine_threadsafe(
164+
self._close(), loop=self._loop
165+
)
166+
# Will attempt to safely shut down tasks for 5s
167+
deconstruct_future.result(timeout=5)
168+
logger.debug("Finished deconstructing")
169+
153170

154171
def connect(instance_connection_string: str, driver: str, **kwargs: Any) -> Any:
155172
"""Uses a Connector object with default settings and returns a database

google/cloud/sql/connector/instance_connection_manager.py

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -280,30 +280,6 @@ async def _async_init() -> None:
280280
init_future = asyncio.run_coroutine_threadsafe(_async_init(), self._loop)
281281
init_future.result()
282282

283-
def __del__(self) -> None:
284-
"""Deconstructor to make sure ClientSession is closed and tasks have
285-
finished to have a graceful exit.
286-
"""
287-
logger.debug("Entering deconstructor")
288-
289-
async def _deconstruct() -> None:
290-
if isinstance(self._current, asyncio.Task):
291-
logger.debug("Waiting for _current to be cancelled")
292-
self._current.cancel()
293-
if isinstance(self._next, asyncio.Task):
294-
logger.debug("Waiting for _next to be cancelled")
295-
self._next.cancel()
296-
if not self._client_session.closed:
297-
logger.debug("Waiting for _client_session to close")
298-
await self._client_session.close()
299-
300-
deconstruct_future = asyncio.run_coroutine_threadsafe(
301-
_deconstruct(), loop=self._loop
302-
)
303-
# Will attempt to safely shut down tasks for 5s
304-
deconstruct_future.result(timeout=5)
305-
logger.debug("Finished deconstructing")
306-
307283
async def _get_instance_data(self) -> InstanceMetadata:
308284
"""Asynchronous function that takes in the futures for the ephemeral certificate
309285
and the instance metadata and generates an OpenSSL context object.
@@ -687,3 +663,14 @@ def _connect_with_pytds(
687663
return pytds.connect(
688664
ip_address, database=db, user=user, password=passwd, sock=sock, **kwargs
689665
)
666+
667+
async def close(self) -> None:
668+
"""Cleanup function to make sure ClientSession is closed and tasks have
669+
finished to have a graceful exit.
670+
"""
671+
logger.debug("Waiting for _current to be cancelled")
672+
self._current.cancel()
673+
logger.debug("Waiting for _next to be cancelled")
674+
self._next.cancel()
675+
logger.debug("Waiting for _client_session to close")
676+
await self._client_session.close()

tests/unit/test_connector.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ def test_connect_enable_iam_auth_error() -> None:
101101
"pg8000",
102102
enable_iam_auth=True,
103103
)
104+
# remove mock_icm to avoid destructor warnings
105+
default_connector._instances = {}
104106

105107

106108
def test_default_Connector_Init() -> None:

tests/unit/test_rate_limiter.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ async def increment() -> None:
6060
assert len(done) == 4
6161
assert len(pending) == 6
6262

63+
# cleanup pending tasks
64+
for task in pending:
65+
task.cancel()
66+
6367

6468
@pytest.mark.asyncio
6569
async def test_rate_limiter_completes_all_tasks(

0 commit comments

Comments
 (0)