From c0a395ac899d0fb55b0a0d0338039dcc52472965 Mon Sep 17 00:00:00 2001 From: Ishaan Jaffer Date: Fri, 20 Feb 2026 17:43:59 -0800 Subject: [PATCH] fix(proxy): add auth reconnect lock timeout budget --- litellm/proxy/utils.py | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/litellm/proxy/utils.py b/litellm/proxy/utils.py index 4cbcc7aa713..840d5dfe4a6 100644 --- a/litellm/proxy/utils.py +++ b/litellm/proxy/utils.py @@ -2289,6 +2289,10 @@ class PrismaClient: self._db_auth_reconnect_timeout_seconds: float = max( 0.5, float(os.getenv("PRISMA_AUTH_RECONNECT_TIMEOUT_SECONDS", "2.0")) ) + self._db_auth_reconnect_lock_timeout_seconds: float = max( + 0.0, + float(os.getenv("PRISMA_AUTH_RECONNECT_LOCK_TIMEOUT_SECONDS", "0.1")), + ) verbose_proxy_logger.debug("Success - Created Prisma Client") def get_request_status( @@ -3587,6 +3591,7 @@ class PrismaClient: reason: str, force: bool = False, timeout_seconds: Optional[float] = None, + lock_timeout_seconds: Optional[float] = None, ) -> bool: """ Attempt to reconnect the Prisma client in a singleflight manner. @@ -3606,7 +3611,7 @@ class PrismaClient: ) return False - async with self._db_reconnect_lock: + async def _attempt_reconnect_inside_lock() -> bool: now = time.time() if ( force is False @@ -3642,6 +3647,28 @@ class PrismaClient: return reconnect_succeeded + if lock_timeout_seconds is None: + 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: + verbose_proxy_logger.debug( + "Skipping DB reconnect attempt due to lock acquisition timeout. reason=%s timeout=%ss", + reason, + lock_timeout_seconds, + ) + return False + + try: + return await _attempt_reconnect_inside_lock() + finally: + self._db_reconnect_lock.release() + async def start_db_health_watchdog_task(self) -> None: """ Start a background task that probes DB health and attempts reconnect on failure.