
    h:                        d dl Z d dlZd dlZd dlmZmZmZmZmZm	Z	m
Z
 d dlmZ d dlmZmZmZmZ d dlmZ d dlmZmZmZmZ  G d de      Z G d	 d
e      Z G d de      Z G d dee      Z G d de      Z G d de      Zy)    N)AsyncIteratorIterableMappingOptionalSequenceTupleType)Redis)
ConnectionConnectionPool
EncodableTSSLConnection)AsyncSentinelCommands)ConnectionErrorReadOnlyErrorResponseErrorTimeoutErrorc                       e Zd Zy)MasterNotFoundErrorN__name__
__module____qualname__     x/var/www/fastuser/data/www/generator.snapmosaic.io/flask_app/venv/lib/python3.12/site-packages/redis/asyncio/sentinel.pyr   r          r   r   c                       e Zd Zy)SlaveNotFoundErrorNr   r   r   r   r   r      r   r   r   c                   r     e Zd Z fdZd Zd Zd Zd Z	 	 ddddd	ed
e	e
   de	e
   de	e   f fdZ xZS )SentinelManagedConnectionc                 P    |j                  d      | _        t        |   di | y )Nconnection_poolr   )popr#   super__init__)selfkwargs	__class__s     r   r&   z"SentinelManagedConnection.__init__   s%    %zz*;<"6"r   c                     d| j                   j                   d| j                   j                   }| j                  r!d| j                   d| j                   }||z  }|dz   S )N<.z,host=z,port=z)>)r)   r   r   hostport)r'   s	host_infos      r   __repr__z"SentinelManagedConnection.__repr__#   s]    ))*!DNN,C,C+DE99 6$))=INA4xr   c                    K   |\  | _         | _        | j                  | j                  j                  d       d {    y 7 w)NF)check_healthretry_socket_connect)r-   r.   connect_check_healthr#   check_connection)r'   addresss     r   
connect_toz$SentinelManagedConnection.connect_to*   sC     &	49''-->>!& ( 
 	
 	
s   :AAAc                 ~  K   | j                   ry | j                  j                  r:| j                  | j                  j	                          d {          d {    y | j                  j                         2 3 d {   }	 | j                  |       d {   c S 7 P7 F7 $7 # t        $ r Y 8w xY w6 t        wN)_readerr#   	is_masterr8   get_master_addressrotate_slavesr   r   )r'   slaves     r   _connect_retryz(SentinelManagedConnection._connect_retry1   s     <<))//(<(<(O(O(Q"QRRR#33AAC  e!%!777	 #RR7&   D
 %$sx   AB=BB=B!B=:B6>B#?B6B=B'B%B'B=!B=#B6%B''	B30B=2B33
B=c                 l   K   | j                   j                  | j                  d        d {   S 7 w)Nc                 ,    t        j                  d      S )Nr   )asynciosleep)errors    r   <lambda>z3SentinelManagedConnection.connect.<locals>.<lambda>A   s    '--* r   )retrycall_with_retryr@   r'   s    r   connectz!SentinelManagedConnection.connect>   s3     ZZ//*
 
 	
 
s   +424FT)disconnect_on_errorpush_requestdisable_decodingtimeoutrK   rL   c                   K   	 t         |   ||||       d {   S 7 # t        $ r< | j                  j                  r$| j                          d {  7   t        d       w xY ww)N)rM   rN   rK   rL   z"The previous master is now a slave)r%   read_responser   r#   r<   
disconnectr   )r'   rM   rN   rK   rL   r)   s        r   rP   z'SentinelManagedConnection.read_responseD   sy     	.!1$7)	 /      		##-- oo'''%&JKK		s1   A*"  " A*" 2A'AA''A*)FN)r   r   r   r&   r1   r8   r@   rJ   boolr   floatrP   __classcell__r)   s   @r   r!   r!      sm    #
%
 "'#'
 04', %
 &e_ tn r   r!   c                       e Zd Zy)SentinelManagedSSLConnectionNr   r   r   r   rW   rW   _   r   r   rW   c                   T     e Zd ZdZ fdZd Z fdZdef fdZd Z	de
fd	Z xZS )
SentinelConnectionPoolz
    Sentinel backed connection pool.

    If ``check_connection`` flag is set to True, SentinelManagedConnection
    sends a PING command right after establishing the connection.
    c                 ^   |j                  d|j                  dd      rt        nt              |d<   |j                  dd      | _        |j                  dd      | _        t        |   di | t        j                  |       | j                  d<   || _        || _        d | _        d | _        y )	Nconnection_classsslFr<   Tr6   r#   r   )getr$   rW   r!   r<   r6   r%   r&   weakrefproxyconnection_kwargsservice_namesentinel_managermaster_addressslave_rr_counter)r'   ra   rb   r(   r)   s       r   r&   zSentinelConnectionPool.__init__k   s    %+ZZ ::eU+ -.&
!"  K6 &

+=u E"6"4;MM$4G01( 0" $r   c           	          d| j                   j                   d| j                   j                   d| j                   d| j                  xr dxs d d	S )Nr+   r,   z	(service=(masterr?   z))>)r)   r   r   ra   r<   rI   s    r   r1   zSentinelConnectionPool.__repr__}   sV    ))*!DNN,C,C+D))*!DNN,Gx,R7+SSVX	
r   c                 >    t         |           d | _        d | _        y r:   )r%   resetrc   rd   )r'   r)   s    r   ri   zSentinelConnectionPool.reset   s    " $r   
connectionc                     | j                    xs3 | j                   xr% | j                  |j                  |j                  fk(  }|xr t        |   |      S r:   )r<   rc   r-   r.   r%   owns_connection)r'   rj   checkr)   s      r   rl   z&SentinelConnectionPool.owns_connection   sR    NN" 
NNXt22z
6XX 	 <0<<r   c                    K   | j                   j                  | j                         d {   }| j                  r0| j                  |k7  r!|| _        | j                  d       d {    |S 7 B7 w)NF)inuse_connections)rb   discover_masterra   r<   rc   rQ   )r'   rc   s     r   r=   z)SentinelConnectionPool.get_master_address   sj     #44DDTEVEVWW>>""n4&4# ooo>>> X ?s!   )A2A.;A2'A0(A20A2returnc                  K   | j                   j                  | j                         d{   }|r| j                  't	        j
                  dt        |      dz
        | _        t        t        |            D ]6  }| j                  dz   t        |      z  | _        || j                     }| 8 	 | j                          d{    t        d| j                        7 7 !# t        $ r Y 'w xY ww)zRound-robin slave balancerNr      zNo slave found for )rb   discover_slavesra   rd   randomrandintlenranger=   r   r   )r'   slaves_r?   s       r   r>   z$SentinelConnectionPool.rotate_slaves   s     ,,<<T=N=NOO$$,(.q#f+/(J%3v;' )-)>)>)Bc&k(Q%t445
	//111 !#6t7H7H6K!LMM P 2" 		sF   )C9C&BC93C* C(C* C9(C* *	C63C95C66C9)r   r   r   __doc__r&   r1   ri   r   rl   r=   r   r>   rT   rU   s   @r   rY   rY   c   s6    %$
%
=* =N] Nr   rY   c                       e Zd ZdZ	 	 	 ddZd Zd Zdedede	fd	Z
defd
Zdee   deeeef      fdZdedeeeef      fdZeefdedee   dee   fdZeefdedee   dee   fdZy)Sentinela~  
    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)
    >>> await master.set('foo', 'bar')
    >>> slave = sentinel.slave_for('mymaster', socket_timeout=0.1)
    >>> await 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           
      "   |5|j                         D ci c]  \  }}|j                  d      s|| }}}|| _        |D 	cg c]  \  }}	t        d||	d| j                   c}	}| _        || _        || _        || _        y c c}}w c c}	}w )Nsocket_)r-   r.   r   )items
startswithsentinel_kwargsr
   	sentinelsmin_other_sentinelsr`   _force_master_ip)
r'   r   r   r   force_master_ipr`   kvhostnamer.   s
             r   r&   zSentinel.__init__   s     "!2!8!8!:Aall9>U1O   / #,
$ CxdCd.B.BC
 $7 !2 /

s   BB"Bc           
        K   t        |j                  dd            }t        |j                  dd            }|rB t        j                  | j                        j
                  |i | d{   }|r|gS |rdS dS | j                  D cg c]'  }t        j                   |j
                  |i |      ) }}t        j                  |  d{   }|r|S t        |      S 7 tc c}w 7 w)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.
        onceFreturn_responsesNT)
rR   r$   ru   choicer   execute_commandrC   Taskgatherall)	r'   argsr(   r   r   responsesentineltasks	responsess	            r   r   zSentinel.execute_command   s      FJJvu-.  

+=u EFJV]]4>>:JJ H   z!'t2U2 !NN
 LL1114B6BC
 
 "..%00	9~#
 1s0   A+C+-C".C+,C$7C+C)C+$C+c                 "   g }| j                   D ]F  }|j                  |j                  j                  d    d|j                  j                  d           H d| j                   d| j                  j
                   ddj                  |       dS )	Nr-   :r.   r+   r,   z(sentinels=[,z])>)r   appendr#   r`   r)   r   join)r'   sentinel_addressesr   s      r   r1   zSentinel.__repr__   s     	H%%++==fEFa++==fEFH	 q!8!8 9388$678=	
r   statera   rq   c                 J    |d   r
|d   s|d   ry|d   | j                   k  ryy)Nr<   is_sdownis_odownFznum-other-sentinelsT)r   )r'   r   ra   s      r   check_master_statezSentinel.check_master_state  s5    [!U:%6%
:K&'$*B*BBr   c                 J  K   t               }t        | j                        D ]  \  }}	 |j                          d{   }|j                  |      }|s3| j                  ||      sF|| j                  d   c| j                  d<   | j                  |<   | j                  | j                  n|d   }||d   fc S  d}	t        |      dkD  rddj                  |       }	t        d	||	       7 # t        t
        f$ r }|j                  | d|       Y d}~d}~ww xY ww)
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.
        Nz - r   ipr.    z : z, zNo master found for )list	enumerater   sentinel_mastersr   r   r   r]   r   r   rw   r   r   )
r'   ra   collected_errorssentinel_nor   masterser   r   
error_infos
             r   rp   zSentinel.discover_master  s@      6%.t~~%> 	)!K ( 9 9 ;; KK-E00E NN1% ?q!4>>+#> ,,8 ))t 
 5=(('	)* 
 1$tyy)9:;<J!$88H"UVV- <#\2  ''8*Cu(=>sK   &D#C1C/C1D#D#(BD#/C11D  DD#D  D#ry   c                 `    g }|D ]&  }|d   s|d   r|j                  |d   |d   f       ( |S )z1Remove slaves that are in an ODOWN or SDOWN stater   r   r   r.   )r   )r'   ry   slaves_aliver?   s       r   filter_slaveszSentinel.filter_slaves6  sM      	>EZ E*$5teFm <=	> r   c                    K   | j                   D ]3  }	 |j                  |       d{   }| j                  |      }|s1|c S  g S 7 # t        t        t        f$ r Y Pw xY ww)z;Returns a list of alive slaves for service ``service_name``N)r   sentinel_slavesr   r   r   r   )r'   ra   r   ry   s       r   rt   zSentinel.discover_slavesA  sr       	H'77EE ''/F	 	 F#]LA s=   A#A	AA	A# A#A		A A#A  A#redis_classconnection_pool_classc                     d|d<   t        | j                        }|j                  |        ||| fi |}|j                  |      S )a  
        Returns a redis client instance for the ``service_name`` master.
        Sentinel client will detect failover and reconnect Redis clients
        automatically.

        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.
        Tr<   dictr`   update	from_poolr'   ra   r   r   r(   r`   r#   s          r   
master_forzSentinel.master_forO  sP    > #{ !7!78  (/dXFWX$$_55r   c                     d|d<   t        | j                        }|j                  |        ||| fi |}|j                  |      S )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.
        Fr<   r   r   s          r   	slave_forzSentinel.slave_forv  sP    0 ${ !7!78  (/dXFWX$$_55r   )r   NN)r   r   r   r{   r&   r   r1   r   strrR   r   rp   r   r   r   r   r   r   rt   r
   rY   r	   r   r   r   r   r   r}   r}      s    > 00@

 C D !W# !WF	w'		%
J./	0		%
J./	0" $)>T	%6%6 %[%6  $$:;	%6T $)>T	66 %[6  $$:;	6r   r}   )rC   ru   r^   typingr   r   r   r   r   r   r	   redis.asyncio.clientr
   redis.asyncio.connectionr   r   r   r   redis.commandsr   redis.exceptionsr   r   r   r   r   r   r!   rW   rY   r}   r   r   r   <module>r      s       T T T &  1 	/ 		 	>
 >B	#<m 	DN^ DNNj6$ j6r   