Ë
    uPêj£  ã                   ó’   — d Z ddlZddlmZmZmZ ddlmZ ddlm	Z	 ddl
mZ erddlmZ eez  ZneZ G d„ d	e«      Z G d
„ d«      Zy)z¯
Wrapper around router cache for health-check-driven routing.

Stores per-deployment health state from background health checks
and exposes it for router candidate filtering.
é    N)ÚTYPE_CHECKINGÚAnyÚFinal)Ú	TypedDict)Úverbose_logger)Ú	DualCache)ÚSpanc                   ó,   — e Zd ZU eed<   eed<   eed<   y)ÚDeploymentHealthStateValueÚ
is_healthyÚ	timestampÚreasonN)Ú__name__Ú
__module__Ú__qualname__ÚboolÚ__annotations__ÚfloatÚstr© ó    úl/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/router_utils/health_state_cache.pyr   r      s   … ØÓØÓØ„Kr   r   c                   ó�   — e Zd ZdZdZdedefd„Zdee	e
f   ddfd	„Zd
edee	   fd„Zddedz  dee	   fd„Zddedz  dee	   fd„Zy)ÚDeploymentHealthCachea  
    Cache for deployment health states produced by background health checks.

    Stores a single dict mapping deployment_id -> DeploymentHealthStateValue.
    Staleness is enforced at read time: entries older than staleness_threshold
    are treated as healthy (unknown).
    z,litellm:health_check:deployment_health_stateÚcacheÚstaleness_thresholdc                 ó    — || _         || _        y ©N)r   r   )Úselfr   r   s      r   Ú__init__zDeploymentHealthCache.__init__)   s   € ØˆŒ
Ø#6ˆÕ r   ÚstatesÚreturnNc           	      óè  — 	 | j                   j                  �/| j                   j                  j                  | j                  «      nd}t	        |t
        «      r|n%| j                   j                  | j                  ¬«      }t	        |t
        «      r|ni }| j                  dz  }t        j                  «       }i |¥|¥j                  «       D ��ci c]0  \  }}t	        |t
        «      r||j                  dd«      z
  |k  r||“Œ2 }	}}| j                   j                  | j                  |	t        |«      ¬«       yc c}}w # t        $ r)}
t        j                  dt        |
«      «       Y d}
~
yd}
~
ww xY w)ap  Merge the given states into the shared cache entry, pruning expired ones.

        Merging instead of replacing lets writers probing different deployment
        scopes (e.g. pods with different background health check allowlists)
        coexist on the one shared entry without erasing each other's results.
        The snapshot is read from Redis when available, since a pod-local read
        would only ever see this writer's own previous merge. When the Redis
        read comes back empty (a miss, or a swallowed connection error), the
        pod-local copy of the last merge is used so peers are not erased.
        N©Úkeyg      ø?r   r   )r%   ÚvalueÚttlzCDeploymentHealthCache::set_deployment_health_states - Exception: %s)r   Úredis_cacheÚ	get_cacheÚ	CACHE_KEYÚ
isinstanceÚdictr   ÚtimeÚitemsÚgetÚ	set_cacheÚintÚ	Exceptionr   Úerrorr   )r   r!   Ú	redis_rawÚrawÚexistingÚexpiry_secondsÚnowÚmodel_idÚstateÚmergedÚes              r   Úset_deployment_health_statesz2DeploymentHealthCache.set_deployment_health_states-   sK  € ð	àDHÇJÁJ×DZÑDZÐDf�—
‘
×&Ñ&×0Ñ0°·±Ô@Ðlpð ô '1°¼DÔ&A™ÀtÇzÁz×G[ÑG[Ð`d×`nÑ`nÐG[ÓGoˆCÜ%/°´TÔ%:™cÀˆHØ$(×$<Ñ$<¸sÑ$BˆNÜŸ™›ˆCð (>¨(Ð'=°fÐ'=×'CÑ'CÓ'E÷á#�H˜eÜ˜e¤TÔ*°°e·i±iÀÈQÓ6OÑ0OÐSaÒ/að ˜%‘ðˆFñ ð
 �J‰J× Ñ Ø—N‘NØÜ˜Ó'ð !õ ùóøô ò 	Ü× Ñ ØUÜ�A“÷ñ ûð	ús*   ‚CD? Ã5D9Ä4D? Ä9D? Ä?	E1ÅE,Å,E1r5   c           	      ó<  — |rt        |t        «      s
t        «       S t        j                  «       }|j	                  «       D ��ch c]K  \  }}t        |t        «      r6|j                  dd«      s$||j                  dd«      z
  | j                  k  r|’ŒM c}}S c c}}w )zHGiven raw cache value, return set of non-stale unhealthy deployment IDs.r   Tr   r   )r+   r,   Úsetr-   r.   r/   r   )r   r5   r8   r9   r:   s        r   Ú_extract_unhealthy_idsz,DeploymentHealthCache._extract_unhealthy_idsP   s‚   € áœ* S¬$Ô/Ü“5ˆLÜ—Y‘Y“[ˆð $'§9¡9£;÷
á�˜%Ü˜%¤Ô&Ø—I‘I˜l¨DÔ1Ø�u—y‘y ¨aÓ0Ñ0°D×4LÑ4LÒLò	 ó
ð 	
ùó 
s   ÁABÚparent_otel_spanc              ƒ   ó  K  — 	 | j                   j                  | j                  ¬«      ƒ d{  –—† }| j                  |«      S 7 Œ# t        $ r3}t        j                  dt        |«      «       t        «       cY d}~S d}~ww xY w­w)zFReturn set of deployment IDs currently marked unhealthy and not stale.r$   NzIDeploymentHealthCache::async_get_unhealthy_deployment_ids - Exception: %s)	r   Úasync_get_cacher*   r@   r2   r   Údebugr   r?   ©r   rA   r5   r<   s       r   Ú"async_get_unhealthy_deployment_idsz8DeploymentHealthCache.async_get_unhealthy_deployment_ids]   sp   è ø€ ð	Ø#Ÿz™z×9Ñ9¸d¿n¹nÐ9ÓM×MˆCØ×.Ñ.¨sÓ3Ð3ð Nùäò 	Ü× Ñ Ø[Ü�A“ôô “5�Lûð	üsD   ‚B„)A ­A®A ÁBÁA Á	BÁ(A<Á6BÁ7BÁ<BÂBc                 óð   — 	 | j                   j                  | j                  ¬«      }| j                  |«      S # t        $ r3}t        j                  dt        |«      «       t        «       cY d}~S d}~ww xY w)zTSync version: return set of deployment IDs currently marked unhealthy and not stale.r$   zCDeploymentHealthCache::get_unhealthy_deployment_ids - Exception: %sN)	r   r)   r*   r@   r2   r   rD   r   r?   rE   s       r   Úget_unhealthy_deployment_idsz2DeploymentHealthCache.get_unhealthy_deployment_idsi   sd   € ð	ØŸ™×-Ñ-°$·.±.Ð-ÓAˆCØ×.Ñ.¨sÓ3Ð3øÜò 	Ü× Ñ ØUÜ�A“ôô “5�Lûð	ús   ‚69 ¹	A5Á(A0Á*A5Á0A5r   )r   r   r   Ú__doc__r*   r   r   r    r,   r   r   r=   r   r?   r@   r	   rF   rH   r   r   r   r   r      s•   „ ñð ?€Ið7˜ið 7¸eó 7ð!°4¸Ð=WÐ8WÑ3Xð !Ð]aó !ðF
¨#ð 
°#°c±(ó 
ñ
ÈÐPTÉð 
Ð`cÐdgÑ`hó 
ñ
¸TÀD¹[ð 
ÐTWÐX[ÑT\ô 
r   r   )rI   r-   Útypingr   r   r   Útyping_extensionsr   Úlitellmr   Úlitellm.caching.cachingr   Úopentelemetry.tracer	   Ú_Spanr   r   r   r   r   ú<module>rP      sJ   ðñó ß ,Ñ ,å 'å "Ý -áÝ1à�3‰;�Dà€Dô ô ÷Uò Ur   