Ë
    uPêj–  ã                   ó�   — U d Z ddlZddlZddlZddlmZ ddlmZ ddlm	Z	 ddl
mZ dZeed<   d	Zeed
<   dZeed<    G d„ d«      Zy)u�  
Application-level graceful shutdown coordination for the LiteLLM proxy.

Kubernetes terminates a pod by sending ``SIGTERM`` and, after
``terminationGracePeriodSeconds``, ``SIGKILL``. By default LiteLLM delegates
the signal to uvicorn and tears down immediately, dropping any in-flight
requests (streaming, batch inference, long-lived calls).

A fixed ``preStop`` sleep can not solve this: it has to be sized for the
*worst-case* request, so it either wastes time on every routine shutdown or is
too short for a long-running request. This manager instead drains based on the
*actual* in-flight request counter (already tracked by
``InFlightRequestsMiddleware``), so a pod terminates as soon as its real
in-flight work is done â€” and never waits longer than ``GRACEFUL_SHUTDOWN_TIMEOUT``.

The state is process-scoped (class-level), matching the per-uvicorn-worker
granularity of ``InFlightRequestsMiddleware``.
é    N)ÚCallable)ÚFinal)Úverbose_proxy_logger)Úget_in_flight_requestsg      >@Ú!DEFAULT_GRACEFUL_SHUTDOWN_TIMEOUTgš™™™™™¹?Ú_DRAIN_POLL_INTERVALg      @Ú_DRAIN_LOG_INTERVALc                   óÞ   — e Zd ZU dZdZeed<   dZedz  ed<   dZ	eed<   e
defd„«       Ze
defd	„«       Ze
dd
„«       Ze
dddeefdedz  dedeg ef   dz  dededefd„«       Ze
dd„«       Zy)ÚGracefulShutdownManagerz˜
    Process-scoped singleton that tracks whether the worker is draining and
    blocks until in-flight requests reach zero (or a timeout elapses).
    FÚ_is_shutting_downNÚ_shutdown_started_atÚ_drain_performedÚreturnc                 ó   — | j                   S )z0Whether this worker has begun graceful shutdown.)r   ©Úclss    úu/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/proxy/shutdown/graceful_shutdown_manager.pyÚis_shutting_downz(GracefulShutdownManager.is_shutting_down/   s   € ð ×$Ñ$Ð$ó    c                 óÀ   — t        j                  d«      }|€t        S 	 t        |«      S # t        t
        f$ r$ t        j                  d|t        «       t        cY S w xY w)z×
        Read GRACEFUL_SHUTDOWN_TIMEOUT (seconds) from the environment on each
        call so deployments can tune it without code changes. Falls back to the
        default on an unset or malformed value.
        ÚGRACEFUL_SHUTDOWN_TIMEOUTz?GRACEFUL_SHUTDOWN_TIMEOUT=%r is not a number; using default %ss)ÚosÚgetenvr   ÚfloatÚ	TypeErrorÚ
ValueErrorr   Úwarning)r   Úraws     r   Úget_timeoutz#GracefulShutdownManager.get_timeout4   s`   € ô —Y‘YÐ:Ó;ˆØˆ;Ü4Ð4ð	5Ü˜“:ÐøÜœ:Ð&ò 	5Ü ×(Ñ(ØQØÜ1ôô
 5Ò4ð	5ús   Ÿ
* ª0AÁAc                 óš   — | j                   ryd| _         t        j                  «       | _        t	        j
                  dt        «       «       y)u¦   
        Mark the worker as draining. Idempotent â€” repeated calls (e.g. SIGTERM
        followed by a preStop hit on /health/drain) do not reset the clock.
        NTz/graceful_shutdown_started in_flight_requests=%s)r   ÚtimeÚ	monotonicr   r   Úinfor   r   s    r   Ústart_shutdownz&GracefulShutdownManager.start_shutdownH   s>   € ð × Ò ØØ $ˆÔÜ#'§>¡>Ó#3ˆÔ Ü×!Ñ!Ø=Ü"Ó$õ	
r   ÚtimeoutÚexclude_selfÚcount_fnÚpoll_intervalÚlog_intervalc              ƒ   ó˜  K  — | j                   ryd| _         |€| j                  «       }|€t        }|rdnd}t        j                  «       } |«       }|}	|dk  rt        d||z
  «      S 	  |«       }
|
|k  r=t        d||
z
  «      }t        j                  d|t        j                  «       |z
  «       |S t        j                  «       |z
  }||k\  r't        j                  d|
||«       t        d||
z
  «      S t        j                  «       }||	z
  |k\  rt        j                  d|
|«       |}	t        j                  |«      ƒ d{  –—†  Œß7 Œ­w)a'  
        Poll the in-flight request counter until it reaches the drain target or
        ``timeout`` seconds elapse.

        Args:
            timeout: Max seconds to wait. Defaults to ``get_timeout()``.
            exclude_self: When the caller is itself an in-flight HTTP request
                (the /health/drain endpoint), set this so the caller's own
                request is not counted as outstanding work.
            count_fn: Source of the current in-flight count. Defaults to the
                live ``InFlightRequestsMiddleware`` counter; injectable for tests.
            poll_interval: Seconds between counter polls.
            log_interval: Minimum seconds between ``drain_waiting`` log lines.

        Returns:
            Number of requests that drained while waiting (>= 0).
        r   TNé   z=graceful_shutdown_complete drained_requests=%s elapsed_s=%.2fuh   graceful_shutdown_timeout in_flight_requests=%s elapsed_s=%.2f timeout_s=%s â€” proceeding with teardownz2drain_waiting in_flight_requests=%s elapsed_s=%.2f)r   r   r   r!   r"   Úmaxr   r#   r   ÚasyncioÚsleep)r   r%   r&   r'   r(   r)   ÚtargetÚstartÚinitialÚlast_logÚcurrentÚdrainedÚelapsedÚnows                 r   Úwait_for_drainz&GracefulShutdownManager.wait_for_drainW   s]  è ø€ ð< ×ÒØØ#ˆÔàˆ?Ø—o‘oÓ'ˆGØÐÜ-ˆHñ *™¨qˆä—~‘~Ó'ˆÙ!›ˆØˆà�aŠ<Ü�q˜' FÑ*Ó+Ð+àÙ“jˆGØ˜&Ò Ü˜a ¨7Ñ!2Ó3�Ü$×)Ñ)ØSØÜ—N‘NÓ$ uÑ,ôð
 �ä—n‘nÓ&¨Ñ.ˆGØ˜'Ò!Ü$×,Ñ,ð@àØØôô ˜1˜g¨Ñ/Ó0Ð0ä—.‘.Ó"ˆCØ�X‰~ Ò-Ü$×)Ñ)ØHØØôð
 �ä—-‘- Ó.×.Ð.ð? ð> /ús   ‚E E
ÅEÅE
c                 ó.   — d| _         d| _        d| _        y)z'Reset state. Intended for use in tests.FN)r   r   r   r   s    r   ÚresetzGracefulShutdownManager.resetª   s   € ð !&ˆÔØ#'ˆÔ Ø$ˆÕr   )r   N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   ÚboolÚ__annotations__r   r   r   Úclassmethodr   r   r$   r   r	   r   Úintr7   r9   © r   r   r   r   %   s  … ñð
 $Ð�tÓ#Ø)-Ð˜% $™,Ó-Ø"Ð�dÓ"àð% ò %ó ð%ð ð5˜Eò 5ó ð5ð& ò
ó ð
ð ð !%Ø"Ø-1Ø3Ø1ñP/à˜‘ðP/ð ðP/ð ˜2˜s˜7Ñ# dÑ*ð	P/ð
 ðP/ð ðP/ð 
òP/ó ðP/ðd ò%ó ñ%r   r   )r=   r-   r   r!   Úcollections.abcr   Útypingr   Úlitellm._loggingr   Ú6litellm.proxy.middleware.in_flight_requests_middlewarer   r   r?   r   r	   r   rB   r   r   ú<module>rG      sR   ðòó& Û 	Û Ý $Ý å 1õð
 ,0Ð ! 5Ó /Ø!Ð �eÓ !Ø Ð �UÓ  ÷J%ò J%r   