
    keJi:                     *   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	m
Z
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          Z G d de
          Z G d de          ZdS )    N)Optional)Redis)SentinelCommands)
ConnectionConnectionPoolSSLConnection)ConnectionErrorReadOnlyErrorResponseErrorTimeoutErrorc                       e Zd ZdS )MasterNotFoundErrorN__name__
__module____qualname__     T/var/www/html/movieo_spanner_bot/venv/lib/python3.11/site-packages/redis/sentinel.pyr   r              Dr   r   c                       e Zd ZdS )SlaveNotFoundErrorNr   r   r   r   r   r      r   r   r   c                   n     e Zd Z fdZd Zd Zd Zd Z	 dddddee	         d	ee	         f fd
Z
 xZS )SentinelManagedConnectionc                 n    |                     d          | _         t                      j        di | d S )Nconnection_poolr   )popr   super__init__)selfkwargs	__class__s     r   r   z"SentinelManagedConnection.__init__   s;    %zz*;<<""6"""""r   c                     | j         }dt          |           j         dt          |           j         d|j         d}| j        rd| j         d| j         }||z  }|S )N<.	(service=z%s)>z,host=z,port=)r   typer   r   service_namehostport)r    pools	host_infos       r   __repr__z"SentinelManagedConnection.__repr__   s    #0T

% 0 0T

(; 0 0)0 0 0 	
 9 	===$)==IIAr   c                 f    |\  | _         | _        |                     | j        j        d           d S )NF)check_healthretry_socket_connect)r)   r*   connect_check_healthr   check_connection)r    addresss     r   
connect_toz$SentinelManagedConnection.connect_to(   sC    &	49!!->!& 	" 	
 	
 	
 	
 	
r   c                    | j         rd S | j        j        r.|                     | j                                                   d S | j                                        D ])}	 |                     |          c S # t          $ r Y &w xY wt          N)_sockr   	is_masterr5   get_master_addressrotate_slavesr	   r   )r    slaves     r   _connect_retryz(SentinelManagedConnection._connect_retry0   s    : 	F) 	%OOD0CCEEFFFFF-;;==  ??511111&   H$$s    A77
BBc                 D    | j                             | j        d           S )Nc                     d S r7   r   )errors    r   <lambda>z3SentinelManagedConnection.connect.<locals>.<lambda>>   s    T r   )retrycall_with_retryr=   r    s    r   connectz!SentinelManagedConnection.connect=   s!    z))$*=?Q?QRRRr   F)disconnect_on_errorpush_requestrF   rG   c                    	 t                                          |||          S # t          $ r1 | j        j        r#|                                  t          d           w xY w)N)disable_decodingrF   rG   z"The previous master is now a slave)r   read_responser
   r   r9   
disconnectr	   )r    rI   rF   rG   r"   s       r   rJ   z'SentinelManagedConnection.read_response@   s    	77((!1$7) )   
  		 		 		#- L !!!%&JKKK		s	   #' ;A")F)r   r   r   r   r.   r5   r=   rE   r   boolrJ   __classcell__r"   s   @r   r   r      s        # # # # #	 	 	
 
 
% % %S S S
  /4',   &d^	
 tn         r   r   c                       e Zd ZdS )SentinelManagedSSLConnectionNr   r   r   r   rP   rP   Y   r   r   rP   c                   &    e Zd Zd Zd Zd Zd ZdS )SentinelConnectionPoolProxyc                     t          j        |          | _        || _        || _        || _        || _        |                                  d S r7   )weakrefrefconnection_pool_refr9   r3   r(   sentinel_managerreset)r    r   r9   r3   r(   rW   s         r   r   z$SentinelConnectionPoolProxy.__init__^   sF     $+;#?#? " 0( 0

r   c                 "    d | _         d | _        d S r7   )master_addressslave_rr_counterrD   s    r   rX   z!SentinelConnectionPoolProxy.resetm   s    " $r   c                     | j                             | j                  }| j        r>| j        |k    r3|| _        |                                 }||                    d           |S )NF)inuse_connections)rW   discover_masterr(   r9   rZ   rV   rK   )r    rZ   r   s      r   r:   z.SentinelConnectionPoolProxy.get_master_addressq   sq    .>>t?PQQ> 	Dd1^CC"0D #6688O***U*CCCr   c              #     K   | j                             | j                  }|r| j        *t	          j        dt          |          dz
            | _        t          t          |                    D ]2}| j        dz   t          |          z  | _        || j                 }|V  3	 |                                 V  n# t          $ r Y nw xY wt          d| j                  )Nr      zNo slave found for )rW   discover_slavesr(   r[   randomrandintlenranger:   r   r   )r    slaves_r<   s       r   r;   z)SentinelConnectionPoolProxy.rotate_slaves|   s      &66t7HII 	$,(.q#f++/(J(J%3v;;''  )-)>)Bc&kk(Q%t45	))++++++" 	 	 	D	 !Lt7H!L!LMMMs   %B< <
C	C	N)r   r   r   r   rX   r:   r;   r   r   r   rR   rR   ]   sU          % % %	 	 	N N N N Nr   rR   c                   ^     e Zd ZdZ fdZd Z fdZed             Z fdZ	d Z
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                    |                     d|                    dd          rt          nt                    |d<   |                    dd          | _        |                    dd          | _        t          | | j        | j        ||          | _         t                      j	        d	i | | j        | j
        d<   || _        || _        d S )
Nconnection_classsslFr9   Tr3   )r   r9   r3   r(   rW   r   r   )getr   rP   r   r9   r3   rR   proxyr   r   connection_kwargsr(   rW   )r    r(   rW   r!   r"   s       r   r   zSentinelConnectionPool.__init__   s    %+ZZ ::eU++/,,.&
 &
!"  K66 &

+=u E E0 n!2%-
 
 

 	""6"""48J01( 0r   c           	          | j         rdnd}dt          |           j         dt          |           j         d| j         d| d	S )Nmasterr<   r$   r%   r&   (z))>)r9   r'   r   r   r(   )r    roles     r   r.   zSentinelConnectionPool.__repr__   sh    >6xxw6T

% 6 6T

(; 6 6)6 6,06 6 6	
r   c                 z    t                                                       | j                                         d S r7   )r   rX   rn   )r    r"   s    r   rX   zSentinelConnectionPool.reset   s.    
r   c                     | j         j        S r7   )rn   rZ   rD   s    r   rZ   z%SentinelConnectionPool.master_address   s    z((r   c                     | j          p| j         o| j        |j        |j        fk    }t	                      }|o|                    |          S r7   )r9   rZ   r)   r*   r   owns_connection)r    
connectioncheckparentr"   s       r   rw   z&SentinelConnectionPool.owns_connection   sT    N" 
NXt2z
6XX 	 ;//
;;;r   c                 4    | j                                         S r7   )rn   r:   rD   s    r   r:   z)SentinelConnectionPool.get_master_address   s    z,,...r   c                 4    | j                                         S )zRound-robin slave balancer)rn   r;   rD   s    r   r;   z$SentinelConnectionPool.rotate_slaves   s    z'')))r   )r   r   r   __doc__r   r.   rX   propertyrZ   rw   r:   r;   rM   rN   s   @r   ri   ri      s         1 1 1 1 1.
 
 
     ) ) X)< < < < </ / /* * * * * * *r   ri   c                   \    e Zd ZdZ	 	 	 ddZd Zd Zd Zd Zd	 Z	d
 Z
eefdZeefdZdS )Sentinelar  
    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.
    r   Nc                      |d |                                 D             }| _         fd|D              _        | _        | _        | _        d S )Nc                 D    i | ]\  }}|                     d           ||S )socket_)
startswith).0kvs      r   
<dictcomp>z%Sentinel.__init__.<locals>.<dictcomp>   s?       Aall9>U>U1  r   c                 <    g | ]\  }}t          ||fi j        S r   )r   sentinel_kwargs)r   hostnamer*   r    s      r   
<listcomp>z%Sentinel.__init__.<locals>.<listcomp>   sB     
 
 
$ (D99D$899
 
 
r   )itemsr   	sentinelsmin_other_sentinelsro   _force_master_ip)r    r   r   r   force_master_ipro   s   `     r   r   zSentinel.__init__   s     " !2!8!8!:!:  O  /
 
 
 
"+
 
 
 $7 !2 /r   c                 n   t          |                    dd                    }t          |                    dd                    }|r/ t          j        | j                  j        |i |}|r|gS |rdndS g }| j        D ]"}|                     |j        |i |           #|r|S t          |          S )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_responsesT)rL   r   rb   choicer   execute_commandappendall)r    argsr!   r   r   response	responsessentinels           r   r   zSentinel.execute_command   s     FJJvu--..  

+=u E EFF 	3Dv}T^44DdUfUUH 3 z!'2ttU2	 	H 	HH5X5tFvFFGGGG 	9~~r   c                    g }| j         D ]4}|                    d                    |j        j                             5dt          |           j         dt          |           j         dd                    |           dS )Nz{host}:{port}r$   r%   z(sentinels=[,z])>)	r   r   
format_mapr   ro   r'   r   r   join)r    sentinel_addressesr   s      r   r.   zSentinel.__repr__  s     	 	H%%**8+C+UVV   =T

% = =T

(; = =88$677= = =	
r   c                 `    |d         r|d         s|d         rdS |d         | j         k     rdS dS )Nr9   is_sdownis_odownFznum-other-sentinelsT)r   )r    stater(   s      r   check_master_statezSentinel.check_master_state&  sJ    [! 	U:%6 	%
:K 	5&'$*BBB5tr   c                 N   t                      }t          | j                  D ]\  }}	 |                                }n8# t          t
          f$ r$}|                    | d|           Y d}~Kd}~ww xY w|                    |          }|rX|                     ||          rB|| j        d         c| j        d<   | j        |<   | j	        | j	        n|d         }||d         fc S d}	t          |          dk    rdd                    |           }	t          d	||	           )
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   ipr*    z : z, zNo master found for )list	enumerater   sentinel_mastersr	   r   r   rm   r   r   rd   r   r   )
r    r(   collected_errorssentinel_nor   masterser   r   
error_infos
             r   r^   zSentinel.discover_master.  sv     66%.t~%>%> 	) 	)!K"3355#\2    ''8(=(=(=(=>>> KK--E )00EE ) N1% ?q!4>+#> ,8 ))t 
 5=((((
  1$$<tyy)9::<<J!"U"U"U"UVVVs   >A3A..A3c                 |    g }|D ]6}|d         s|d         r|                     |d         |d         f           7|S )z1Remove slaves that are in an ODOWN or SDOWN stater   r   r   r*   )r   )r    rf   slaves_aliver<   s       r   filter_slaveszSentinel.filter_slavesQ  s\     	> 	>EZ  E*$5 teFm <====r   c                     | j         D ]Q}	 |                    |          }n# t          t          t          f$ r Y 2w xY w|                     |          }|r|c S Rg S )z;Returns a list of alive slaves for service ``service_name``)r   sentinel_slavesr	   r   r   r   )r    r(   r   rf   s       r   ra   zSentinel.discover_slavesZ  s     	 	H!11,??#]LA   ''//F 	s   !;;c                     d|d<   t          | j                  }|                    |           |                     ||| fi |          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.
        Tr9   dictro   update	from_poolr    r(   redis_classconnection_pool_classr!   ro   s         r   
master_forzSentinel.master_forf  sd    > #{ !788  ((($$!!,JJ8IJJ
 
 	
r   c                     d|d<   t          | j                  }|                    |           |                     ||| fi |          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.
        Fr9   r   r   s         r   	slave_forzSentinel.slave_for  sd    0 ${ !788  ((($$!!,JJ8IJJ
 
 	
r   )r   NN)r   r   r   r}   r   r   r.   r   r^   r   ra   r   ri   r   r   r   r   r   r   r      s         > 0 0 0 00  8	
 	
 	
  !W !W !WF  
 
 
 4	$
 $
 $
 $
R 4	
 
 
 
 
 
r   r   )rb   rT   typingr   redis.clientr   redis.commandsr   redis.connectionr   r   r   redis.exceptionsr	   r
   r   r   r   r   r   rP   rR   ri   r   r   r   r   <module>r      s                 + + + + + + F F F F F F F F F F           	 	 	 	 	/ 	 	 		 	 	 	 	 	 	 	> > > > >
 > > >B	 	 	 	 	#<m 	 	 	-N -N -N -N -N -N -N -N`:* :* :* :* :*^ :* :* :*z_
 _
 _
 _
 _
 _
 _
 _
 _
 _
r   