
    IiE9                     
   S SK r S SKrS SKJr  S SKJr  S SKJr  S SKJ	r	J
r
Jr  S SKJrJrJrJr  S SKJr   " S S	\5      r " S
 S\5      r " S S\	5      r " S S\\5      r " S S5      r " S S\
5      r " S S\5      rg)    N)Optional)Redis)SentinelCommands)
ConnectionConnectionPoolSSLConnection)ConnectionErrorReadOnlyErrorResponseErrorTimeoutError)str_if_bytesc                       \ rS rSrSrg)MasterNotFoundError    N__name__
__module____qualname____firstlineno____static_attributes__r       4/venv/lib/python3.13/site-packages/redis/sentinel.pyr   r          r   r   c                       \ rS rSrSrg)SlaveNotFoundError   r   Nr   r   r   r   r   r      r   r   r   c                   z   ^  \ rS rSrU 4S jrS rU 4S jrS rS r SSSS.S	\	\
   S
\	\
   4U 4S jjjjrSrU =r$ )SentinelManagedConnection   c                 R   > UR                  S5      U l        [        TU ]  " S0 UD6  g )Nconnection_poolr   )popr"   super__init__)selfkwargs	__class__s     r   r%   "SentinelManagedConnection.__init__   s%    %zz*;<"6"r   c                     U R                   nS[        U 5      R                   S[        U 5      R                   SUR                   S3nU R
                  (       a   SU R
                   SU R                   3nX#-  nU$ )N<.	(service=z%s)>z,host=z,port=)r"   typer   r   service_namehostport)r&   pools	host_infos       r   __repr__"SentinelManagedConnection.__repr__   sy    ##T
%%&aT
(;(;'<))*$0 	
 99 6$))=IAr   c                    > Uu  U l         U l        [        TU ]  5         U R                  R
                  (       a:  U R                  S5        [        U R                  5       5      S:w  a  [        S5      eg g )NPINGPONGzPING failed)
r0   r1   r$   connectr"   check_connectionsend_commandr   read_responser	   )r&   addressr(   s     r   
connect_to$SentinelManagedConnection.connect_to$   sc    &	4900f%D..01V;%m44 < 1r   c                 D   U R                   (       a  g U R                  R                  (       a*  U R                  U R                  R	                  5       5        g U R                  R                  5        H  n U R                  U5      s  $    [        e! [         a     M,  f = fN)_sockr"   	is_masterr?   get_master_addressrotate_slavesr	   r   )r&   slaves     r   _connect_retry(SentinelManagedConnection._connect_retry,   s    ::))OOD00CCEF--;;=??511 >
 %$ ' s   6B
BBc                 P    U R                   R                  U R                  S 5      $ )Nc                     g rB   r   )errors    r   <lambda>3SentinelManagedConnection.connect.<locals>.<lambda>:   s    Tr   )retrycall_with_retryrH   r&   s    r   r:   !SentinelManagedConnection.connect9   s     zz))$*=*=?QRRr   F)disconnect_on_errorpush_requestrS   rT   c                   >  [         TU ]  UUUS9$ ! [         a8    U R                  R                  (       a  U R                  5         [        S5      ee f = f)N)disable_decodingrS   rT   z"The previous master is now a slave)r$   r=   r
   r"   rD   
disconnectr	   )r&   rV   rS   rT   r(   s       r   r=   'SentinelManagedConnection.read_response<   sc    	7(!1$7) )  
  		##-- !%&JKK		s
    AA)r"   r0   r1   )F)r   r   r   r   r%   r5   r?   rH   r:   r   boolr=   r   __classcell__r(   s   @r   r   r      sU    #	5%S
  /4', &d^	
 tn r   r   c                       \ rS rSrSrg)SentinelManagedSSLConnectionU   r   Nr   r   r   r   r]   r]   U   r   r   r]   c                   ,    \ rS rSrS rS rS rS rSrg)SentinelConnectionPoolProxyY   c                     [         R                  " U5      U l        X l        X0l        X@l        XPl        U R                  5         g rB   )weakrefrefconnection_pool_refrD   r;   r/   sentinel_managerreset)r&   r"   rD   r;   r/   rf   s         r   r%   $SentinelConnectionPoolProxy.__init__Z   s5     $+;;#? " 0( 0

r   c                      S U l         S U l        g rB   )master_addressslave_rr_counterrQ   s    r   rg   !SentinelConnectionPoolProxy.reseti   s    " $r   c                     U R                   R                  U R                  5      nU R                  (       a8  U R                  U:w  a(  Xl        U R                  5       nUb  UR                  SS9  U$ )NF)inuse_connections)rf   discover_masterr/   rD   rj   re   rW   )r&   rj   r"   s      r   rE   .SentinelConnectionPoolProxy.get_master_addressm   se    ..>>t?P?PQ>>d11^C"0 #668O***U*Cr   c              #     #    U R                   R                  U R                  5      nU(       a  U R                  c(  [        R
                  " S[        U5      S-
  5      U l        [        [        U5      5       H5  nU R                  S-   [        U5      -  U l        XR                     nUv   M7      U R                  5       v   [        SU R                  < 35      e! [         a     N%f = f7f)Nr      zNo slave found for )rf   discover_slavesr/   rk   randomrandintlenrangerE   r   r   )r&   slaves_rG   s       r   rF   )SentinelConnectionPoolProxy.rotate_slavesx   s     &&66t7H7HI$$,(.q#f+/(J%3v;')-)>)>)Bc&k(Q%445 (
	))++ !#6t7H7H6K!LMM # 		s*   B/C-2C C-
C*'C-)C**C-)r;   re   rD   rj   rf   r/   rk   N)	r   r   r   r   r%   rg   rE   rF   r   r   r   r   r`   r`   Y   s    %	Nr   r`   c                   f   ^  \ rS rSrSrU 4S jrS rU 4S jr\S 5       r	U 4S jr
S rS	 rS
rU =r$ )SentinelConnectionPool   z
Sentinel backed connection pool.

If ``check_connection`` flag is set to True, SentinelManagedConnection
sends a PING command right after establishing the connection.
c                   > UR                  SUR                  SS5      (       a  [        O[        5      US'   UR                  SS5      U l        UR                  SS5      U l        [        U U R                  U R
                  UUS9U l        [        TU ]$  " S	0 UD6  U R                  U R                  S'   Xl        X l        g )
Nconnection_classsslFrD   Tr;   )r"   rD   r;   r/   rf   r"   r   )getr#   r]   r   rD   r;   r`   proxyr$   r%   connection_kwargsr/   rf   )r&   r/   rf   r'   r(   s       r   r%   SentinelConnectionPool.__init__   s    %+ZZ ::eU++ -.&
!"  K6 &

+=u E0 nn!22%-

 	"6"48JJ01( 0r   c           	          U R                   (       a  SOSnS[        U 5      R                   S[        U 5      R                   SU R                   SU S3	$ )NmasterrG   r+   r,   r-   (z))>)rD   r.   r   r   r/   )r&   roles     r   r5   SentinelConnectionPool.__repr__   sR    >>xwT
%%&aT
(;(;'<))*!D66	
r   c                 V   > [         TU ]  5         U R                  R                  5         g rB   )r$   rg   r   )r&   r(   s    r   rg   SentinelConnectionPool.reset   s    

r   c                 .    U R                   R                  $ rB   )r   rj   rQ   s    r   rj   %SentinelConnectionPool.master_address   s    zz(((r   c                    > U R                   (       + =(       d8    U R                   =(       a%    U R                  UR                  UR                  4:H  n[	        5       nU=(       a    UR                  U5      $ rB   )rD   rj   r0   r1   r$   owns_connection)r&   
connectioncheckparentr(   s       r   r   &SentinelConnectionPool.owns_connection   sZ    NN" 
NNXt22z
6XX 	 ;//
;;r   c                 6    U R                   R                  5       $ rB   )r   rE   rQ   s    r   rE   )SentinelConnectionPool.get_master_address   s    zz,,..r   c                 6    U R                   R                  5       $ )zRound-robin slave balancer)r   rF   rQ   s    r   rF   $SentinelConnectionPool.rotate_slaves   s    zz''))r   )r;   rD   r   rf   r/   )r   r   r   r   __doc__r%   r5   rg   propertyrj   r   rE   rF   r   rZ   r[   s   @r   r|   r|      s?    1.
 ) )</* *r   r|   c                   h    \ rS rSrSr   SS jrS rS rS rS r	S	 r
S
 r\\4S jr\\4S jrSrg)Sentinel   a  
Redis Sentinel cluster client

>>> from redis.sentinel import Sentinel
>>> sentinel = Sentinel([('localhost', 26379)], socket_timeout=0.1)
>>> master = sentinel.master_for('mymaster', socket_timeout=0.1)
>>> master.set('foo', 'bar')
>>> slave = sentinel.slave_for('mymaster', socket_timeout=0.1)
>>> slave.get('foo')
b'bar'

``sentinels`` is a list of sentinel nodes. Each node is represented by
a pair (hostname, port).

``min_other_sentinels`` defined a minimum number of peers for a sentinel.
When querying a sentinel, if it doesn't meet this threshold, responses
from that sentinel won't be considered valid.

``sentinel_kwargs`` is a dictionary of connection arguments used when
connecting to sentinel instances. Any argument that can be passed to
a normal Redis connection can be specified here. If ``sentinel_kwargs`` is
not specified, any socket_timeout and socket_keepalive options specified
in ``connection_kwargs`` will be used.

``connection_kwargs`` are keyword arguments that will be used when
establishing a connection to a Redis server.
Nc           	      *   Uc<  UR                  5        VVs0 s H  u  pgUR                  S5      (       d  M  Xg_M!     nnnX0l        U VV	s/ s H  u  p[        X40 U R                  D6PM     sn	nU l        X l        XPl        X@l        g s  snnf s  sn	nf )Nsocket_)items
startswithsentinel_kwargsr   	sentinelsmin_other_sentinelsr   _force_master_ip)
r&   r   r   r   force_master_ipr   kvhostnamer1   s
             r   r%   Sentinel.__init__   s     "!2!8!8!:!:all9>U!:    / #,
"+ (9D$8$89"+
 $7 !2 /

s   B	B	"Bc                 >   [        UR                  SS5      5      nSUR                  5       ;   a  UR                  S5        U(       a1  [        R
                  " U R                  5      R                  " U0 UD6  gU R                   H  nUR                  " U0 UD6  M     g)z
Execute Sentinel command in sentinel nodes.
once - If set to True, then execute the resulting command on a single
node at random, rather than across the entire sentinel cluster.
onceFT)rY   r   keysr#   rt   choicer   execute_command)r&   argsr'   r   sentinels        r   r   Sentinel.execute_command   s     FJJvu-.V[[]"JJvMM$..)994J6J  !NN(($9&9 +r   c                    / nU R                    H7  nUR                  SR                  UR                  R                  5      5        M9     S[        U 5      R                   S[        U 5      R                   SSR                  U5       S3$ )Nz{host}:{port}r+   r,   z(sentinels=[,z])>)	r   append
format_mapr"   r   r.   r   r   join)r&   sentinel_addressesr   s      r   r5   Sentinel.__repr__  s    H%%**8+C+C+U+UV '
 T
%%&aT
(;(;'<388$678=	
r   c                 j    US   (       a  US   (       d
  US   (       a  gUS   U R                   :  a  gg)NrD   is_sdownis_odownFznum-other-sentinelsT)r   )r&   stater/   s      r   check_master_stateSentinel.check_master_state  s5    [!U:%6%
:K&'$*B*BBr   c                 N   [        5       n[        U R                  5       H  u  p4 UR                  5       nUR                  U5      nU(       d  M0  U R                  Xq5      (       d  MH  UU R                  S   sU R                  S'   U R                  U'   U R                  b  U R                  OUS   nXS   4s  $    Sn	[        U5      S:  a  SSR                  U5       3n	[        S	U< U	 35      e! [        [
        4 a"  nUR                  U SU< 35         SnAM  SnAff = f)
z
Asks sentinel servers for the Redis master's address corresponding
to the service labeled ``service_name``.

Returns a pair (address, port) or raises MasterNotFoundError if no
master is found.
z - Nr   ipr1    z : z, zNo master found for )list	enumerater   sentinel_mastersr	   r   r   r   r   r   rv   r   r   )
r&   r/   collected_errorssentinel_nor   masterser   r   
error_infos
             r   ro   Sentinel.discover_master  s1     6%.t~~%>!K"335 KK-Eu00EE NN1% ?q!4>>+#> ,,8 ))t 
 =((' &?* 
 1$tyy)9:;<J!$88H"UVV+ $\2  ''8*Cu(=>s   C22D$DD$c                 z    / nU H2  nUS   (       d
  US   (       a  M  UR                  US   US   45        M4     U$ )z1Remove slaves that are in an ODOWN or SDOWN stater   r   r   r1   )r   )r&   rx   slaves_aliverG   s       r   filter_slavesSentinel.filter_slavesB  sF    EZ E*$5teFm <=  r   c                     U R                    H1  n UR                  U5      nU R                  U5      nU(       d  M/  Us  $    / $ ! [        [        [        4 a     MO  f = f)z;Returns a list of alive slaves for service ``service_name``)r   sentinel_slavesr	   r   r   r   )r&   r/   r   rx   s       r   rs   Sentinel.discover_slavesK  sc    H!11,? ''/Fv ' 	 $]LA s   AAAc                     SUS'   [        U R                  5      nUR                  U5        UR                  U" X40 UD65      $ )a  
Returns a redis client instance for the ``service_name`` master.

A :py:class:`~redis.sentinel.SentinelConnectionPool` class is
used to retrieve the master's address before establishing a new
connection.

NOTE: If the master's address has changed, any cached connections to
the old master are closed.

By default clients will be a :py:class:`~redis.Redis` instance.
Specify a different class to the ``redis_class`` argument if you
desire something different.

The ``connection_pool_class`` specifies the connection pool to
use.  The :py:class:`~redis.sentinel.SentinelConnectionPool`
will be used by default.

All other keyword arguments are merged with any connection_kwargs
passed to this class and passed to the connection pool as keyword
arguments to be used to initialize Redis connections.
TrD   dictr   update	from_poolr&   r/   redis_classconnection_pool_classr'   r   s         r   
master_forSentinel.master_forW  sN    : #{ !7!78  ($$!,J8IJ
 	
r   c                     SUS'   [        U R                  5      nUR                  U5        UR                  U" X40 UD65      $ )a  
Returns redis client instance for the ``service_name`` slave(s).

A SentinelConnectionPool class is used to retrieve the slave's
address before establishing a new connection.

By default clients will be a :py:class:`~redis.Redis` instance.
Specify a different class to the ``redis_class`` argument if you
desire something different.

The ``connection_pool_class`` specifies the connection pool to use.
The SentinelConnectionPool will be used by default.

All other keyword arguments are merged with any connection_kwargs
passed to this class and passed to the connection pool as keyword
arguments to be used to initialize Redis connections.
FrD   r   r   s         r   	slave_forSentinel.slave_for{  sN    0 ${ !7!78  ($$!,J8IJ
 	
r   )r   r   r   r   r   )r   NN)r   r   r   r   r   r%   r   r5   r   ro   r   rs   r   r|   r   r   r   r   r   r   r   r      sR    > 00"	
!WF
 4	"
N 4	
r   r   )rt   rc   typingr   redis.clientr   redis.commandsr   redis.connectionr   r   r   redis.exceptionsr	   r
   r   r   redis.utilsr   r   r   r   r]   r`   r|   r   r   r   r   <module>r      s        + F F X X $	/ 		 	>
 >B	#<m 	-N -N`:*^ :*zR
 R
r   