
    ng\jG                     2   % S SK r S SKrS SKrS SKJrJr  S SKJr  S SKJ	r	J
r
JrJrJr  S SKJr  S SKJr  S SKJrJr  S SKJr  S SKJr  S SKJr  S S	KJr  S S
KJ r   S SK!J"r"  \\\4   r#S\S\$4S jr%S\&S\S\&4S jr'Sr(Sr)Sr*Sr+Sr,\RZ                  " \.5      r/ " S S\5      r0 " S S\5      r1 " S S\15      r2 " S S\25      r3 " S S\25      r4 " S S \25      r5 " S! S"\5      r6\6Rn                  r8\6\9S#'    " S$ S%\05      r: " S& S'\:5      r; " S( S)\:5      r<g)*    N)ABCabstractmethod)Enum)ListOptionalTupleTypeUnion)Redis)RedisCluster)DEFAULT_TIMEOUTAsyncHTTPClientWrapper)	NoBackoff)
HttpClient)UnhealthyDatabaseException)Retryclsreturnc                     [         R                  " U R                  5      n[        S UR                  R                  5        5       5      $ )z7Extract parameter names from a class's __init__ method.c              3      #    U  HU  u  pUS :w  d  M  UR                   [        R                  R                  [        R                  R                  4;   d  MQ  Uv   MW     g7f)selfN)kindinspect	ParameterPOSITIONAL_OR_KEYWORDKEYWORD_ONLY).0nameparams      \/home/edenadmin/noVNC/venv/lib/python3.13/site-packages/redis/asyncio/multidb/healthcheck.py	<genexpr>#_get_init_params.<locals>.<genexpr>   sX      	1KD6> 	 JJ33**

 	1s   AA A	A)r   	signature__init__	frozenset
parametersitems)r   sigs     r    _get_init_paramsr)      s=    


CLL
)C 	>>//1	 	 	    kwargsc                 |    [        U5      nU R                  5        VVs0 s H  u  p4X2;   d  M  X4_M     snn$ s  snnf )zJFilter kwargs to only include parameters accepted by the class's __init__.)r)   r'   )r+   r   allowedkvs        r    _filter_kwargsr0   %   s4    s#G#\\^<^TQq|DAD^<<<s   88      g      ?i  c                       \ rS rSrSr\\S\4S j5       5       r\\S\	4S j5       5       r
\\S\	4S j5       5       r\S\S\4S j5       rS	rg
)HealthCheck4   z
Health check interface.
r   c                     g)z*Number of probes to execute health checks.N r   s    r    health_check_probesHealthCheck.health_check_probes9        	r*   c                     g)z"Delay between health check probes.Nr7   r8   s    r    health_check_delayHealthCheck.health_check_delay?   r;   r*   c                     g)zCTimeout for the full health check operation (including all probes).Nr7   r8   s    r    health_check_timeout HealthCheck.health_check_timeoutE   r;   r*   	hc_clientc                    #    g7f)a0  
Function to determine the health status.

Args:
    database: The database being checked
    hc_client: A Redis client (AsyncRedis or AsyncRedisCluster) to use for
        health checks. This client follows topology changes automatically.

Returns:
    True if the database is healthy, False otherwise.
Nr7   r   databaserB   s      r    check_healthHealthCheck.check_healthK   s
      	   r7   N)__name__
__module____qualname____firstlineno____doc__propertyr   intr9   floatr=   r@   AsyncRedisClientTboolrF   __static_attributes__r7   r*   r    r4   r4   4   s     S    E    e    6G D  r*   r4   c                       \ rS rSrSr\S\\   S\4S j5       r	\S\S\4S j5       r
\S\4S j5       r\SS
 j5       rSrg	)HealthCheckPolicy[   z!
Health checks execution policy.
health_checksr   c                    #    g7f)z8Execute health checks and return database health status.Nr7   )r   rW   rE   s      r    executeHealthCheckPolicy.execute`   
      	rH   health_checkc                    #    g7fz/
Executes health check against given database.
Nr7   r   r\   rE   s      r    _executeHealthCheckPolicy._executee   
     
 	rH   c                    #    g7f)z-
Get a health check client for the database.
Nr7   )r   rE   s     r    
get_clientHealthCheckPolicy.get_clientl   rb   rH   Nc                    #    g7f)Close all health check clients.Nr7   r8   s    r    closeHealthCheckPolicy.closes   r[   rH   r7   r   N)rI   rJ   rK   rL   rM   r   r   r4   rR   rY   r`   rQ   rd   rh   rS   r7   r*   r    rU   rU   [   s     4+< 4   ; T   ,=    r*   rU   c                   j    \ rS rSrSrS rS\\   S\4S jr	S\
4S jrSS	 jr\S
\S\4S j5       rSrg)AbstractHealthCheckPolicyy   z
Abstract health check policy.
c                     0 U l         g N_clientsr8   s    r    r$   "AbstractHealthCheckPolicy.__init__~   s	    68r*   rW   r   c                   ^ ^#    S[         4UU 4S jjn[        R                  " U Vs/ s H
  oC" U5      PM     snSS06I Sh  vN nU H.  n[        U[        5      (       a  [        STU5      eU(       a  M.    g   gs  snf  N>7f)z
Execute all health checks concurrently with individual timeouts.
Each health check runs with its own timeout, and all run in parallel.

All exception handling is centralized here - _execute() methods just
propagate exceptions naturally.
r\   c                 ~   >#    [         R                  " TR                  U T5      U R                  S9I S h  vN $  N7f)N)timeout)asynciowait_forr`   r@   )r\   rE   r   s    r    execute_with_timeout?AbstractHealthCheckPolicy.execute.<locals>.execute_with_timeout   s:      ))lH5$99   s   3=;=return_exceptionsTNzUnhealthy databaseF)r4   rv   gather
isinstance	Exceptionr   )r   rW   rE   rx   hcresultsresults   ` `    r    rY   !AbstractHealthCheckPolicy.execute   s     	[ 	 	  1>?2"2&?
"
 
 F&),,01ExQWXXV   @
s!   $BA=
BB0B8Bc           
        #    [        U5      nU R                  R                  U5      nUGc  [        UR                  [
        [        45      (       a7  UR                  R                  5       n[        U[
        5      n[        S0 UD6nGO([        UR                  [        [        45      (       a  UR                  R                  5       R                  5       n[        U[        5      nUR                  R                  nU(       a  US   nUR                  R                  n[        US[        USS5      5      n	[        SUR                  UR                   UR"                  UR$                  U	UR                  R&                  S.UD6nO,[)        S5      e[+        S[-        UR                  5       35      eX0R                  U'   U$ 7f)	z
Get or create a health check client for the database.

Creates a single client instance per database that follows topology
changes automatically. For cluster databases, the client handles
node discovery and slot mapping internally.
r   require_full_coverage_require_full_coverageT)hostportdynamic_startup_nodesaddress_remapr   retryz?Cluster client has no nodes - cannot create health check clientzUnsupported client type: r7   )idrq   getr|   client
AsyncRedis	SyncRedisget_connection_kwargsr0   AsyncRedisClusterSyncRedisClustercopystartup_nodesnodes_managergetattrr   r   _dynamic_startup_nodesr   r   
ValueError	TypeErrortype)
r   rE   db_idr   conn_kwargsfiltered_kwargsr   
first_noder   r   s
             r    rd   $AbstractHealthCheckPolicy.get_client   s     8""5)>(//J	+BCC&ooCCE"0j"I#6o6HOO.?AQ-RSS 'ooCCEJJL"0>O"P ( = = !.q!1J$,OO$A$AM
 -4%//GN-)
 / '__'__.;.R.R&3&A&A.C&oo33 *F %Y   ";D<Q;R STT#)MM% s   F?GNc                 0  #    U R                   R                  5        Vs/ s H'  n[        R                  " UR	                  5       5      PM)     nnU(       a  [        R
                  " USS06I Sh  vN   U R                   R                  5         gs  snf  N$7f)rg   rz   TN)rq   valuesrv   create_taskacloser{   clear)r   r   close_taskss      r    rh   AbstractHealthCheckPolicy.close   s{      @D}}?S?S?U
?UVG0?U 	 
 ..+FFFF

 Gs   B.B"B/B0%Br\   c                    #    g7fr^   r7   r_   s      r    r`   "AbstractHealthCheckPolicy._execute   rb   rH   rp   rj   )rI   rJ   rK   rL   rM   r$   r   r4   rR   rY   rQ   rd   rh   r   r`   rS   r7   r*   r    rl   rl   y   sZ    94+< 4 B5,= 5n	 ; T  r*   rl   c                   *    \ rS rSrSrS\S\4S jrSrg)HealthyAllPolicy   zE
Policy that returns True if all health check probes are successful.
r\   r   c                 .  #    U R                  U5      I Sh  vN nUR                  n[        U5       HW  nUR                  X#5      I Sh  vN nU(       d    gXTS-
  :  d  M/  [        R
                  " UR                  5      I Sh  vN   MY     g Nw NF N7f)r
Executes health check against given database.

Uses a single client that handles topology changes automatically.
NF   T)rd   r9   rangerF   rv   sleepr=   )r   r\   rE   r   probesattemptr   s          r    r`   HealthyAllPolicy._execute   s      x0011V}G'44XFFF!#mmL$C$CDDD %  1 G
 Es9   BB2B
BB"#BB
BBBr7   N	rI   rJ   rK   rL   rM   r4   rR   r`   rS   r7   r*   r    r   r      s    ; T r*   r   c                   *    \ rS rSrSrS\S\4S jrSrg)HealthyMajorityPolicyi  a  
Policy that returns True if a majority of health check probes are successful.

Majority means more than half must pass:
- 3 probes: need 2+ to pass (1 failure allowed)
- 4 probes: need 3+ to pass (1 failure allowed, tie = unhealthy)
- 5 probes: need 3+ to pass (2 failures allowed)
r\   r   c                   #    UR                   nUS-
  S-  nU R                  U5      I Sh  vN nSn[        U5       Hc  n UR                  X%5      I Sh  vN nU(       d  US-  nUS:  a    gXsS-
  :  d  M;  [
        R                  " UR                  5      I Sh  vN   Me     g Ny NQ! [         a  n	U	nUS-  nUS:  a  Ue Sn	A	NYSn	A	ff = f N37f)r   r      Nr   FTr9   rd   r   rF   r}   rv   r   r=   )
r   r\   rE   r   allowed_unsuccessful_probesr   last_exceptionr   r   es
             r    r`   HealthyMajorityPolicy._execute  s      11 (.za&7#x00V}G)+88JJ/14/2Q6$ !#mmL$C$CDDD! %$ + 1
 K  )!"+q0+.2(( 3	) Es]   )CB%CB)B'B),C8#CC
C'B))
C3CCCCr7   Nr   r7   r*   r    r   r     s    ; T r*   r   c                   *    \ rS rSrSrS\S\4S jrSrg)HealthyAnyPolicyi2  zL
Policy that returns True if at least one health check probe is successful.
r\   r   c                 z  #    UR                   nSnU R                  U5      I Sh  vN n[        U5       HY  n UR                  X%5      I Sh  vN nU(       a    g XcS-
  :  d  M1  [
        R                  " UR                  5      I Sh  vN   M[     U(       a  Ueg Nv NP! [         a  nUn SnANUSnAff = f N/7f)r   NTr   Fr   )	r   r\   rE   r   r   r   r   r   r   s	            r    r`   HealthyAnyPolicy._execute7  s      11x00V}G#+88JJ  !#mmL$C$CDDD %   % 1 K  #!"# Es\   #B;BB;B BB 	B;&#B;	B9
B;B  
B6*B1,B;1B66B;r7   Nr   r7   r*   r    r   r   2  s    ; T r*   r   c                        \ rS rSr\r\r\r	Sr
g)HealthCheckPoliciesiT  r7   N)rI   rJ   rK   rL   r   HEALTHY_ALLr   HEALTHY_MAJORITYr   HEALTHY_ANYrS   r7   r*   r    r   r   T  s    "K,"Kr*   r   DEFAULT_HEALTH_CHECK_POLICYc                       \ rS rSr\\\4S\S\S\4S jjr	\
S\4S j5       r\
S\4S j5       r\
S\4S	 j5       r\S
\S\4S j5       rSrg)AbstractHealthChecki]  r9   r=   r@   c                 J    US:  a  [        S5      eXl        X l        X0l        g )Nr   z*health_check_probes must be greater than 0)r   _health_check_probes_health_check_delay_health_check_timeout)r   r9   r=   r@   s       r    r$   AbstractHealthCheck.__init__^  s*     "IJJ$7!#5 %9"r*   r   c                     U R                   $ ro   )r   r8   s    r    r9   'AbstractHealthCheck.health_check_probesj  s    (((r*   c                     U R                   $ ro   )r   r8   s    r    r=   &AbstractHealthCheck.health_check_delayn  s    '''r*   c                     U R                   $ ro   )r   r8   s    r    r@   (AbstractHealthCheck.health_check_timeoutr  s    )))r*   rB   c                    #    g 7fro   r7   rD   s      r    rF    AbstractHealthCheck.check_healthv  s     rH   )r   r   r   N)rI   rJ   rK   rL   DEFAULT_HEALTH_CHECK_PROBESDEFAULT_HEALTH_CHECK_DELAYDEFAULT_HEALTH_CHECK_TIMEOUTrO   rP   r$   rN   r9   r=   r@   r   rQ   rR   rF   rS   r7   r*   r    r   r   ]  s     $?$>&B	
: 
: "
: $	
: )S ) ) (E ( ( *e * * 6G D  r*   r   c                   *    \ rS rSrSrS\S\4S jrSrg)PingHealthChecki{  z%
Health check based on PING command.
rB   r   c                    #    [        U[        5      (       a  UR                  S5      I S h  vN $ UR                  5       nU H-  nUR                  R                  S5      I S h  vN (       a  M-    g   g NH N7f)NPINGFT)r|   r   execute_command	get_nodesredis_connection)r   rE   rB   	all_nodesnodes        r    rF   PingHealthCheck.check_health  sm     i,,"226::: "++-I!!22BB6JJJ  "  ;
 Ks'   *A9A57A9$A7%A90A97A9r7   N)	rI   rJ   rK   rL   rM   rQ   rR   rF   rS   r7   r*   r    r   r   {  s    
6G 
D 
r*   r   c                      ^  \ rS rSrSrS\\SSSSSSSS\\\	4S\
S\
S\S	\\\\4      S
\S\\   S\\   S\\\\4      S\\   S\\   S\\   S\
S\S\4U 4S jjjrS\S\4S jrSrU =r$ )LagAwareHealthChecki  z
Health check available for Redis Enterprise deployments.
Verify via REST API that the database is healthy based on different lags.
i$  NTrest_api_portlag_aware_tolerancehttp_timeout
auth_basic
verify_tlsca_fileca_pathca_dataclient_cert_fileclient_key_fileclient_key_passwordr9   r=   r@   c                    > [        [        UU[        [        5       SS9UUUUU	U
US9
5      U l        Xl        X l        [        TU ]!  UUUS9  g)a8  
Initialize LagAwareHealthCheck with the specified parameters.

Args:
    rest_api_port: Port number for Redis Enterprise REST API (default: 9443)
    lag_aware_tolerance: Tolerance in lag between databases in MS (default: 100)
    http_timeout: Request timeout in seconds (default: DEFAULT_TIMEOUT)
    auth_basic: Tuple of (username, password) for basic authentication
    verify_tls: Whether to verify TLS certificates (default: True)
    ca_file: Path to CA certificate file for TLS verification
    ca_path: Path to CA certificates directory for TLS verification
    ca_data: CA certificate data as string or bytes
    client_cert_file: Path to client certificate file for mutual TLS
    client_key_file: Path to client private key file for mutual TLS
    client_key_password: Password for encrypted client private key
r   )retries)
ru   r   r   r   r   r   r   r   r   r   )r9   r=   r@   N)	r   r   r   r   _http_client_rest_api_port_lag_aware_tolerancesuperr$   )r   r   r   r   r   r   r   r   r   r   r   r   r9   r=   r@   	__class__s                  r    r$   LagAwareHealthCheck.__init__  sk    H 3$%IK3%!1 /$7
 ,$7! 31!5 	 	
r*   rB   r   c                   #    UR                   c  [        S5      e[        UR                  [        [
        45      (       a  UR                  R                  5       S   nO'UR                  R                  5       S   R                  nUR                    SU R                   3nX@R                  R                  l        SnU R                  R                  S5      I Sh  vN  H3  nUS    H'  nUS   U:X  a  Un  M  US	    H  nX:X  d  M
  Un  M%     M)     M5     Uc   [        R                  S
5        [        S5      eSUS    SU R                   3n	U R                  R                  U	SS9I Sh  vN   g N N7f)z
Check database health via Redis Enterprise REST API.

Note: The client parameter is not used for this health check as it
relies on the REST API instead of Redis protocol. The client is
accepted for interface compatibility.
Nz[Database health check url is not set. Please check DatabaseConfig for the current database.r   r   :z/v1/bdbs	endpointsdns_nameaddrz8LagAwareHealthCheck failed: Couldn't find a matching bdbzCould not find a matching bdbz	/v1/bdbs/uidz=/availability?extend_check=lag&availability_lag_tolerance_ms=F)expect_jsonT)health_check_urlr   r|   r   r   r   r   r   r   r   r   base_urlr   loggerwarningr   )
r   rE   rB   db_hostr   matching_bdbbdbendpointr   urls
             r    rF    LagAwareHealthCheck.check_health  s     $$,m  hoo
I'>??oo;;=fEG oo//1!499G//0$2E2E1FG,4  ) **..z:::C,J'72#&L %V,D'* - - ; NNUV<== U+, -??C?X?X>Y[ 	 ##CU#;;; / ;( 	<s+   CE5E1(E5A$E5+E3,E53E5)r   r   r   )rI   rJ   rK   rL   rM   DEFAULT_LAG_AWARE_TOLERANCEr   r   r   r   rO   rP   r   r   strrR   r
   bytesr$   rQ   rF   rS   __classcell__)r   s   @r    r   r     s    "#>-04!%!%/3*.)--1#>$>&B%8
8
 !8
 	8

 U38_-8
 8
 #8
 #8
 %U
+,8
 #3-8
 "#8
 &c]8
  !!8
" "#8
$ $%8
 8
t/6G /D / /r*   r   )=rv   r   loggingabcr   r   enumr   typingr   r   r   r	   r
   redis.asyncior   r   redis.asyncio.clusterr   r   redis.asyncio.http.http_clientr   r   redis.backoffr   redis.clientr   redis.clusterr   redis.http.http_clientr   redis.multidb.exceptionr   redis.retryr   rQ   r%   r)   dictr0   r   DEFAULT_HEALTH_CHECK_INTERVALr   r   r	  	getLoggerrI   r  r4   rU   rl   r   r   r   r   r   r   __annotations__r   r   r   r7   r*   r    <module>r     s@      #  5 5 - C R # + : - >  *&778 $ 9 =4 =d =t =    !     " 			8	$$# $N <q 1 qh0 2)5 )X0 D#$ # 4G3R3R 0 R+ <) $o- or*   