@@ -200,7 +200,7 @@ def get_provider(
200200 )
201201 if provider :
202202 # ----- Host lock for random choice -----
203- host_name = provider .get ("host " ) or provider .get ("server " )
203+ host_name = provider .get ("id " ) or provider .get ("api_host " )
204204 if host_name :
205205 host_key = self ._host_key (host_name )
206206 ok_host = int (
@@ -234,8 +234,8 @@ def get_provider(
234234 )
235235 if ok == 1 :
236236 # ----- Host lock for deterministic choice -----
237- host_name = provider .get ("host " ) or provider .get (
238- "server "
237+ host_name = provider .get ("id " ) or provider .get (
238+ "api_host "
239239 )
240240 if host_name :
241241 host_key = self ._host_key (host_name )
@@ -290,90 +290,11 @@ def put_provider(
290290 # Release provider lock
291291 self .redis_client .hdel (redis_key , provider_field )
292292 # Release host lock if it was acquired
293- host_key = provider .get ("__host_key " )
293+ host_key = provider .get ("id" ) or provider . get ( "api_host " )
294294 if host_key :
295295 self ._release_host_script (keys = [host_key ], args = [])
296296 except Exception :
297297 raise
298298
299299 provider .pop ("__chosen_field" , None )
300300 provider .pop ("__host_key" , None )
301-
302- # ----------------------------------------------------------------------
303- # Helper methods
304- # ----------------------------------------------------------------------
305- def _try_acquire_random_provider (
306- self , redis_key : str , providers : List [Dict ]
307- ) -> Optional [Dict ]:
308- """
309- Attempt to lock a provider chosen at random.
310-
311- The method works in three stages:
312-
313- 1. **Shuffle** – a shallow copy of ``providers`` is shuffled so that each
314- provider has an equal probability of being tried first. The original
315- list is left untouched.
316- 2. **Atomic acquisition** – each shuffled provider is passed to the
317- ``_acquire_script`` Lua script which atomically sets the corresponding
318- Redis hash field to ``'true'`` *only if* it is currently ``'false'`` or
319- missing. The first provider for which the script returns ``1`` is
320- considered successfully acquired.
321- 3. **Fallback** – if none of the providers can be locked (e.g., all are
322- currently in use), the method falls back to the *first* provider in the
323- original ``providers`` list, marks its ``"__chosen_field"`` for
324- consistency, and returns it. This fallback mirrors the behaviour of
325- the non‑random acquisition path and ensures the caller always receives
326- a provider dictionary (or ``None`` when ``providers`` is empty).
327-
328- Parameters
329- ----------
330- redis_key : str
331- The Redis hash key associated with the model (e.g., ``model:<name>``).
332- providers : List[Dict]
333- A list of provider configuration dictionaries. Each dictionary must
334- contain sufficient information for :meth:`_provider_field` to generate
335- a unique field name within the Redis hash.
336-
337- Returns
338- -------
339- Optional[Dict]
340- The selected provider dictionary with an additional ``"__chosen_field"``
341- entry indicating the Redis hash field that was locked. Returns ``None``
342- only when the input ``providers`` list is empty.
343-
344- Raises
345- ------
346- Exception
347- Propagates any unexpected exceptions raised by the Lua script execution;
348- callers may catch these to implement retry or logging logic.
349-
350- Notes
351- -----
352- * The random selection is *non‑deterministic* on each call; however, the
353- fallback to the first provider ensures deterministic behaviour when
354- all providers are currently busy.
355- * The method does **not** block; it returns immediately after trying all
356- shuffled providers.
357- """
358- shuffled = providers [:]
359- random .shuffle (shuffled )
360- for provider in shuffled :
361- provider_field = self ._provider_field (provider )
362- try :
363- ok = int (
364- self ._acquire_script (keys = [redis_key ], args = [provider_field ])
365- )
366- if ok == 1 :
367- provider ["__chosen_field" ] = provider_field
368- return provider
369- except Exception :
370- continue
371- return None
372-
373- def _get_active_providers (
374- self , model_name : str , providers : List [Dict ]
375- ) -> List [Dict ]:
376- active_providers = self ._monitor .get_providers (
377- model_name = model_name , only_active = True
378- )
379- return active_providers
0 commit comments