fix(proxy): avoid lock leak race in reconnect lock timeout path

This commit is contained in:
Ishaan Jaffer 2026-02-20 18:04:01 -08:00
parent b53c34280a
commit aa71695915

View file

@ -3651,12 +3651,35 @@ class PrismaClient:
async with self._db_reconnect_lock:
return await _attempt_reconnect_inside_lock()
try:
await asyncio.wait_for(
self._db_reconnect_lock.acquire(),
timeout=lock_timeout_seconds,
)
except asyncio.TimeoutError:
lock_acquired_by_timeout_task = False
async def _acquire_reconnect_lock() -> bool:
nonlocal lock_acquired_by_timeout_task
await self._db_reconnect_lock.acquire()
lock_acquired_by_timeout_task = True
return True
acquire_task = asyncio.create_task(_acquire_reconnect_lock())
done, _pending = await asyncio.wait(
{acquire_task},
timeout=lock_timeout_seconds,
return_when=asyncio.FIRST_COMPLETED,
)
if acquire_task not in done:
acquire_task.cancel()
try:
await acquire_task
except asyncio.CancelledError:
pass
except Exception:
pass
# Defensive cleanup for timeout/cancel race on Python 3.9-3.11.
if lock_acquired_by_timeout_task:
try:
self._db_reconnect_lock.release()
except RuntimeError:
pass
verbose_proxy_logger.debug(
"Skipping DB reconnect attempt due to lock acquisition timeout. reason=%s timeout=%ss",
reason,
@ -3664,6 +3687,16 @@ class PrismaClient:
)
return False
try:
acquire_task.result()
except Exception as lock_acquire_err:
verbose_proxy_logger.debug(
"Skipping DB reconnect attempt due to lock acquisition error. reason=%s error=%s",
reason,
lock_acquire_err,
)
return False
try:
return await _attempt_reconnect_inside_lock()
finally: