Skip to content

Commit d08a9b8

Browse files
authored
Break connection internal circular reference (#774)
The connection will now terminate itself immediately if there is no external reference to it. Refs #772
1 parent edefd69 commit d08a9b8

File tree

3 files changed

+12
-9
lines changed

3 files changed

+12
-9
lines changed

asyncpg/connect_utils.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -729,7 +729,7 @@ async def _connect(*, loop, timeout, connection_class, record_class, **kwargs):
729729
for addr in addrs:
730730
before = time.monotonic()
731731
try:
732-
con = await _connect_addr(
732+
return await _connect_addr(
733733
addr=addr,
734734
loop=loop,
735735
timeout=timeout,
@@ -740,8 +740,6 @@ async def _connect(*, loop, timeout, connection_class, record_class, **kwargs):
740740
)
741741
except (OSError, asyncio.TimeoutError, ConnectionError) as ex:
742742
last_error = ex
743-
else:
744-
return con
745743
finally:
746744
timeout -= time.monotonic() - before
747745

asyncpg/connection.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@
99
import asyncpg
1010
import collections
1111
import collections.abc
12+
import functools
1213
import itertools
1314
import sys
1415
import time
1516
import traceback
1617
import warnings
18+
import weakref
1719

1820
from . import compat
1921
from . import connect_utils
@@ -70,7 +72,8 @@ def __init__(self, protocol, transport, loop,
7072
self._stmt_cache = _StatementCache(
7173
loop=loop,
7274
max_size=config.statement_cache_size,
73-
on_remove=self._maybe_gc_stmt,
75+
on_remove=functools.partial(
76+
_weak_maybe_gc_stmt, weakref.ref(self)),
7477
max_lifetime=config.max_cached_statement_lifetime)
7578

7679
self._stmts_to_close = set()
@@ -2260,4 +2263,10 @@ def _check_record_class(record_class):
22602263
)
22612264

22622265

2266+
def _weak_maybe_gc_stmt(weak_ref, stmt):
2267+
self = weak_ref()
2268+
if self is not None:
2269+
self._maybe_gc_stmt(stmt)
2270+
2271+
22632272
_uid = 0

tests/test_connect.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
import asyncio
99
import contextlib
10-
import gc
1110
import ipaddress
1211
import os
1312
import platform
@@ -1448,14 +1447,11 @@ class TestConnectionGC(tb.ClusterTestCase):
14481447

14491448
async def _run_no_explicit_close_test(self):
14501449
con = await self.connect()
1450+
await con.fetchval("select 123")
14511451
proto = con._protocol
14521452
conref = weakref.ref(con)
14531453
del con
14541454

1455-
gc.collect()
1456-
gc.collect()
1457-
gc.collect()
1458-
14591455
self.assertIsNone(conref())
14601456
self.assertTrue(proto.is_closed())
14611457

0 commit comments

Comments
 (0)