
    <"ri0                         d dl Z d dlZd dl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mZmZmZ d dlmZ  G d de      Z G d	 d
e      Z G d de      Z G d de      Z G d d      Zy)    N)AsyncIteratorIterableMappingSequenceTupleType)Redis)
ConnectionConnectionPool
EncodableTSSLConnection)ConnectionErrorReadOnlyErrorResponseErrorTimeoutError)str_if_bytesc                       e Zd Zy)MasterNotFoundErrorN__name__
__module____qualname__     Y/var/www/fortnox.pascalinesoft.com/venv/lib/python3.12/site-packages/aioredis/sentinel.pyr   r          r   r   c                       e Zd Zy)SlaveNotFoundErrorNr   r   r   r   r   r      r   r   r   c                   >     e Zd Z fdZd Z fdZd Z fdZ xZS )SentinelManagedConnectionc                     |j                  d      | _        |j                  dd      st        t        |   di | y t        |   di | y )Nconnection_poolsslFr   )popr"   superr   __init__)selfkwargs	__class__s     r   r&   z"SentinelManagedConnection.__init__   sG    %zz*;<zz%'-/9&9 G&v&r   c                     | j                   }| j                  j                   d|j                   }| j                  r!d| j                   d| j
                   }||z  }|dz   S )N	<service=z,host=z,port=>)r"   r)   r   service_namehostport)r'   pools	host_infos       r   __repr__z"SentinelManagedConnection.__repr__"   sb    ##~~&&'y1B1B0CD99 6$))=INA3wr   c                 "  K   |\  | _         | _        t        |           d {    | j                  j
                  rI| j                  d       d {    t        | j                          d {         dk7  rt        d      y y 7 d7 77 w)NPINGPONGzPING failed)
r.   r/   r%   connectr"   check_connectionsend_commandr   read_responser   )r'   addressr)   s     r   
connect_toz$SentinelManagedConnection.connect_to*   s     &	49go00##F+++$"4"4"6676A%m44 B 1 	 +6s3   !BB	.BBB0B1BBB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_masterr<   get_master_addressrotate_slavesr   r   )r'   slaves     r   r7   z!SentinelManagedConnection.connect2   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                    K   	 t         |           d {   S 7 # t        $ r< | j                  j                  r$| j                          d {  7   t        d       w xY ww)Nz"The previous master is now a slave)r%   r:   r   r"   r@   
disconnectr   r'   r)   s    r   r:   z'SentinelManagedConnection.read_response?   s^     	.0000 		##-- oo'''%&JKK		s1   A%  A% 2A"AA""A%)	r   r   r   r&   r3   r<   r7   r:   __classcell__r)   s   @r   r    r       s!    '5% r   r    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t              |d<   |j                  dd      | _        |j                  dd      | _        t        |   di | t        j                  |       | j                  d<   || _
        || _        d | _        d | _        y )Nconnection_classr@   Tr8   Fr"   r   )getr    r$   r@   r8   r%   r&   weakrefproxyconnection_kwargsr-   sentinel_managermaster_addressslave_rr_counter)r'   r-   rQ   r(   r)   s       r   r&   zSentinelConnectionPool.__init__V   s    %+ZZ 9&
!"  K6 &

+=u E"6"4;MM$4G01( 0" $r   c                 x    | j                   j                   d| j                   d| j                  xr dxs d dS )Nr+   (masterrC   z)>)r)   r   r-   r@   )r'   s    r   r3   zSentinelConnectionPool.__repr__c   sC    ~~&&'))*!DNN,Gx,R7+SSUW	
r   c                 >    t         |           d | _        d | _        y r>   )r%   resetrR   rS   rF   s    r   rX   zSentinelConnectionPool.reseti   s    " $r   
connectionc                     | j                    xs3 | j                   xr% | j                  |j                  |j                  fk(  }|xr t        |   |      S r>   )r@   rR   r.   r/   r%   owns_connection)r'   rY   checkr)   s      r   r[   z&SentinelConnectionPool.owns_connectionn   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)rQ   discover_masterr-   r@   rR   rE   )r'   rR   s     r   rA   z)SentinelConnectionPool.get_master_addresst   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 )rQ   discover_slavesr-   rS   randomrandintlenrangerA   r   r   )r'   slaves_rC   s       r   rB   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&   r3   rX   r
   r[   rA   r   rB   rG   rH   s   @r   rJ   rJ   N   s6    %
%
=* =N] Nr   rJ   c                       e Zd ZdZ	 	 d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 aioredis.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_sentinelsrP   )	r'   rr   rs   rq   rP   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   A>A>"Bc                    g }| j                   D ]F  }|j                  |j                  j                  d    d|j                  j                  d           H | j                  j
                   ddj                  |       dS )Nr.   :r/   z<sentinels=[,z]>)rr   appendr"   rP   r)   r   join)r'   sentinel_addressessentinels      r   r3   zSentinel.__repr__   s     	H%%++==fEFa++==fEFH	
 ..))*,sxx@R7S6TTVWWr   stater-   r`   c                 J    |d   r
|d   s|d   ry|d   | j                   k  ryy)Nr@   is_sdownis_odownFznum-other-sentinelsT)rs   )r'   r~   r-   s      r   check_master_statezSentinel.check_master_state   s5    [!U:%6%
:K&'$*B*BBr   c                 |  K   t        | j                        D ]|  \  }}	 |j                          d{   }|j                  |      }|s3| j                  ||      sF|| j                  d   c| j                  d<   | j                  |<   |d   |d   fc S  t        d|      7 r# t        t        f$ r Y 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.
        Nr   ipr/   zNo master found for )	enumeraterr   sentinel_mastersr   r   rM   r   r   )r'   r-   sentinel_nor}   mastersr~   s         r   r_   zSentinel.discover_master   s      &/t~~%> 	2!K ( 9 9 ;; KK-E00E NN1% ?q!4>>+#> T{E&M11	2 "$88H"IJJ <#\2 sD   B<B'B%B'B<B<AB<%B''B96B<8B99B<rh   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/   )rz   )r'   rh   slaves_aliverC   s       r   filter_slaveszSentinel.filter_slaves   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)rr   sentinel_slavesr   r   r   r   )r'   r-   r}   rh   s       r   rc   zSentinel.discover_slaves   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                 z    d|d<   t        | j                        }|j                  |        | ||| fi |      S )a  
        Returns a redis client instance for the ``service_name`` master.

        A :py:class:`~redis.sentinel.SentinelConnectionPool` class is
        used to retrive 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@   r"   dictrP   updater'   r-   r   r   r(   rP   s         r   
master_forzSentinel.master_for  sO    : #{ !7!78  (1d&7
 	
r   c                 z    d|d<   t        | j                        }|j                  |        | ||| fi |      S )a  
        Returns redis client instance for the ``service_name`` slave(s).

        A SentinelConnectionPool class is used to retrive 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   r   s         r   	slave_forzSentinel.slave_for*  sO    0 ${ !7!78  (1d&7
 	
r   )r   N)r   r   r   rj   r&   r3   r   strboolr   r_   r   r   r   r   r   r   rc   r	   rJ   r   r   r   r   r   r   rl   rl      s    > 	3,X C D K# K.	w'		%
J./	0		%
J./	0" $)>T	$
$
 %[$
  $$:;	$
R $)>T	

 %[
  $$:;	
r   rl   )rd   rN   typingr   r   r   r   r   r   aioredis.clientr	   aioredis.connectionr
   r   r   r   aioredis.exceptionsr   r   r   r   aioredis.utilsr   r   r   r    rJ   rl   r   r   r   <module>r      si      J J ! U U  (	/ 		 	3 3l?N^ ?NDy
 y
r   