Skip to content

Commit

Permalink
CRF: don't return if not should_free_conn
Browse files Browse the repository at this point in the history
Also trigger GC to collect unused connections after entering starving mode
  • Loading branch information
fantix committed Feb 14, 2024
1 parent 508bb34 commit a0372ae
Showing 1 changed file with 20 additions and 16 deletions.
36 changes: 20 additions & 16 deletions edb/server/connpool/pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -856,15 +856,17 @@ def _tick(self) -> None:
# the starving blocks.

for block in list(self._blocks.values()):
while block.count_conns() > block.count_waiters():
while self._should_free_conn(block):
if (conn := block.try_steal()) is None:
# no more from this block
break

elif not self._maybe_free_conn(block, conn):
elif not self._maybe_free_into_starving_blocks(
block, conn
):
# put back the last stolen connection if we
# don't need to steal anymore
block.release(conn)
self._release_unused(block, conn)
return

else:
Expand Down Expand Up @@ -983,14 +985,11 @@ def _should_free_conn(self, from_block: Block[C]) -> bool:

return True

def _maybe_free_conn(
def _maybe_free_into_starving_blocks(
self,
from_block: Block[C],
conn: C,
) -> bool:
if not self._should_free_conn(from_block):
return False

label, to_block = self._find_most_starving_block()
if to_block is None or to_block is from_block:
return False
Expand Down Expand Up @@ -1204,23 +1203,28 @@ def release(self, dbname: str, conn: C, *, discard: bool=False) -> None:

self._maybe_schedule_tick()

if not self._maybe_free_conn(block, conn):
if not (
self._should_free_conn(block)
and self._maybe_free_into_starving_blocks(block, conn)
):
if discard:
# Concurrent `acquire()` may be waiting to reuse the released
# connection here - as we should discard this one, let's just
# schedule a new one in the same block.
self._schedule_discard(block, conn)
self._schedule_new_conn(block)
return
else:
self._release_unused(block, conn)

block.release(conn)
def _release_unused(self, block: Block[C], conn: C) -> None:
block.release(conn)

# Only request for GC if the connection is released unused
self._gc_requests += 1
if self._gc_requests == 1:
# Only schedule GC for the very first request - following
# requests will be grouped into the next GC
self._get_loop().call_later(self._gc_interval, self._run_gc)
# Only request for GC if the connection is released unused
self._gc_requests += 1
if self._gc_requests == 1:
# Only schedule GC for the very first request - following
# requests will be grouped into the next GC
self._get_loop().call_later(self._gc_interval, self._run_gc)

async def prune_inactive_connections(self, dbname: str) -> None:
try:
Expand Down

0 comments on commit a0372ae

Please sign in to comment.