Skip to content

Commit 3231508

Browse files
committed
feat: moved the guard function to Pool class and made some improvement on implementation
1 parent 2c95068 commit 3231508

File tree

1 file changed

+42
-51
lines changed

1 file changed

+42
-51
lines changed

asyncpg/pool.py

Lines changed: 42 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -287,56 +287,6 @@ def _maybe_cancel_inactive_callback(self) -> None:
287287
self._inactive_callback.cancel()
288288
self._inactive_callback = None
289289

290-
def _can_deactivate_inactive_connection(self) -> bool:
291-
"""Return True if an idle connection may be deactivated (trimmed).
292-
293-
Constraints:
294-
- Do not trim if there are waiters in the pool queue (including acquiring).
295-
- Do not trim below pool min size (leave at least `minsize` open connections).
296-
- Keep at least one idle connection available (i.e., at least 2 idle holders so
297-
trimming one still leaves one idle).
298-
"""
299-
pool = getattr(self, "_pool", None)
300-
if pool is None:
301-
# No pool state; allow default trimming behavior.
302-
return True
303-
304-
# Follow original logic: if pool is closing, handle as default (allow trim).
305-
if getattr(pool, "_closing", False):
306-
return True
307-
308-
minsize = int(getattr(pool, "_minsize", 0) or 0)
309-
310-
# Compute the number of tasks waiting to acquire a connection.
311-
q = getattr(pool, "_queue", None)
312-
if q is not None:
313-
getters = getattr(q, "_getters", None)
314-
waiters = len(getters) if getters is not None else 0
315-
else:
316-
waiters = 0
317-
318-
# Include tasks currently in the process of acquiring.
319-
waiters += int(getattr(pool, "_acquiring", 0) or 0)
320-
321-
# Count open (live) connections and how many of them are idle.
322-
open_conns = 0
323-
idle = 0
324-
holders = list(getattr(pool, "_holders", []) or [])
325-
for h in holders:
326-
if getattr(h, "_con", None) is not None:
327-
open_conns += 1
328-
if not getattr(h, "_in_use", None):
329-
idle += 1
330-
331-
# Conditions to allow trimming one idle connection:
332-
# - No waiters.
333-
# - Trimming one won't drop below minsize (so open_conns - 1 >= minsize).
334-
# - After trimming one idle, at least one idle remains (so idle >= 2).
335-
return (
336-
waiters == 0 and
337-
(open_conns - 1) >= minsize and
338-
idle >= 2
339-
)
340290

341291
def _deactivate_inactive_connection(self) -> None:
342292
if self._in_use is not None:
@@ -345,7 +295,7 @@ def _deactivate_inactive_connection(self) -> None:
345295

346296
if self._con is not None:
347297
# Only deactivate if doing so respects pool size and demand constraints.
348-
if not self._can_deactivate_inactive_connection():
298+
if not self._pool.is_safe_to_close_connection():
349299
# Still mark this holder as available and keep the connection.
350300
# Re-arm the inactivity timer so we can reevaluate later.
351301
self._setup_inactive_callback()
@@ -1064,6 +1014,47 @@ async def expire_connections(self):
10641014
"""
10651015
self._generation += 1
10661016

1017+
def safe_to_close_connection(self):
1018+
"""
1019+
Return True if an idle connection may be deactivated (trimmed).
1020+
1021+
Constraints:
1022+
- Do not trim if there are waiters in the pool queue.
1023+
- Do not trim below pool min size (leave at least `minsize` open connections).
1024+
- Keep at least one idle connection available (i.e., at least 2 idle holders so
1025+
trimming one still leaves one idle).
1026+
"""
1027+
1028+
# Follow original logic: if pool is closing, handle as default (allow trim).
1029+
if self.is_closing():
1030+
return True
1031+
1032+
if self._queue is not None:
1033+
getters = getattr(self._queue, "_getters", [])
1034+
waiters = len(getters)
1035+
else:
1036+
waiters = 0
1037+
1038+
# Count open (live) connections and how many of them are idle.
1039+
open_conns = 0
1040+
idle = 0
1041+
holders = list(self._holders or [])
1042+
for h in holders:
1043+
if h._con is not None:
1044+
open_conns += 1
1045+
if h.is_idle():
1046+
idle += 1
1047+
1048+
# Conditions to allow trimming one idle connection:
1049+
# - No waiters.
1050+
# - Trimming one won't drop below minsize (so open_conns - 1 >= minsize).
1051+
# - After trimming one idle, at least one idle remains (so idle >= 2).
1052+
return (
1053+
waiters == 0 and
1054+
(open_conns - 1) >= self._minsize and
1055+
idle >= 2
1056+
)
1057+
10671058
def _check_init(self):
10681059
if not self._initialized:
10691060
if self._initializing:

0 commit comments

Comments
 (0)