mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-07 02:59:05 +00:00
fix(vertex): serialize credentials.refresh() across threads via _sync_refresh_lock
refresh_auth is invoked from three call sites that can run on different threads (sync get_access_token, async slow path via asyncify, and the background proactive refresh task). Only the sync path was protected by _sync_refresh_lock, so a concurrent sync + async/background call could invoke google-auth's Credentials.refresh() on the same object from two threads simultaneously, mutating internal credential state. Move the lock acquisition into refresh_auth itself; the lock is an RLock so reentrant acquisition from the sync path remains safe. Co-authored-by: Yassin Kortam <yassin@berri.ai>
This commit is contained in:
parent
0570b16b75
commit
1bc0cf375a
1 changed files with 11 additions and 1 deletions
|
|
@ -366,7 +366,17 @@ class VertexBase:
|
|||
except ImportError:
|
||||
raise ImportError(GOOGLE_IMPORT_ERROR_MESSAGE)
|
||||
|
||||
credentials.refresh(Request())
|
||||
# Serialize all refreshes on this VertexBase across threads.
|
||||
# ``credentials.refresh()`` is not safe to call concurrently on the
|
||||
# same credentials object, and this method is invoked from three
|
||||
# places that can run on different threads:
|
||||
# - sync ``get_access_token`` (already holds ``_sync_refresh_lock``)
|
||||
# - the async slow path (via ``asyncify`` in a worker thread)
|
||||
# - the background proactive refresh task (via ``asyncify``)
|
||||
# ``_sync_refresh_lock`` is an ``RLock`` so reentrant acquisition
|
||||
# from the sync path is safe.
|
||||
with self._sync_refresh_lock:
|
||||
credentials.refresh(Request())
|
||||
|
||||
def _acquire_async_refresh_lock(self, credential_cache_key: tuple) -> asyncio.Lock:
|
||||
"""Increment the refcount and return the lock for ``credential_cache_key``.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue