Skip to content

Commit

Permalink
chore: improve connector.close (#985)
Browse files Browse the repository at this point in the history
  • Loading branch information
jackwotherspoon authored Jan 26, 2024
1 parent 63f1288 commit 48a9ccb
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 7 deletions.
22 changes: 15 additions & 7 deletions google/cloud/sql/connector/connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,15 +308,17 @@ async def __aexit__(

def close(self) -> None:
"""Close Connector by stopping tasks and releasing resources."""
close_future = asyncio.run_coroutine_threadsafe(
self.close_async(), loop=self._loop
)
# Will attempt to safely shut down tasks for 5s
close_future.result(timeout=5)
if self._loop.is_running():
close_future = asyncio.run_coroutine_threadsafe(
self.close_async(), loop=self._loop
)
# Will attempt to safely shut down tasks for 5s
close_future.result(timeout=5)
# if background thread exists for Connector, clean it up
if self._thread:
# stop event loop running in background thread
self._loop.call_soon_threadsafe(self._loop.stop)
if self._loop.is_running():
# stop event loop running in background thread
self._loop.call_soon_threadsafe(self._loop.stop)
# wait for thread to finish closing (i.e. loop to stop)
self._thread.join()

Expand All @@ -327,6 +329,12 @@ async def close_async(self) -> None:
*[instance.close() for instance in self._instances.values()]
)

def __del__(self) -> None:
"""Close Connector as part of garbage collection"""
# only want to call destructor when used for sync connections
if self._thread:
self.close()


async def create_async_connector(
ip_type: IPTypes = IPTypes.PUBLIC,
Expand Down
13 changes: 13 additions & 0 deletions tests/unit/test_connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,16 @@ def test_Connector_close_kills_thread() -> None:
connector.close()
# check that connector thread is no longer running
assert connector._thread.is_alive() is False


def test_Connector_close_called_multiple_times() -> None:
"""Test that Connector.close can be called multiple times."""
# open and close Connector object
connector = Connector()
# verify background thread exists
assert connector._thread
connector.close()
# check that connector thread is no longer running
assert connector._thread.is_alive() is False
# call connector.close a second time
connector.close()

0 comments on commit 48a9ccb

Please sign in to comment.