a
    xd-                     @   s   d dl Z d dlZd dlmZ d dlmZmZ d dlmZm	Z	m
Z
mZ d dlmZmZmZ G dd deZG dd	 d	eZG d
d deZG dd deZG dd deZdS )    N)Redis)ConnectionPool
Connection)ConnectionErrorResponseErrorReadOnlyErrorTimeoutError)	iteritems	nativestrxrangec                   @   s   e Zd ZdS )MasterNotFoundErrorN__name__
__module____qualname__ r   r   F/var/www/html/Ranjet/env/lib/python3.9/site-packages/redis/sentinel.pyr      s   r   c                   @   s   e Zd ZdS )SlaveNotFoundErrorNr   r   r   r   r   r      s   r   c                       sD   e Zd Z fddZdd Z fddZdd Z fd	d
Z  ZS )SentinelManagedConnectionc                    s&   | d| _tt| jf i | d S )Nconnection_pool)popr   superr   __init__)selfkwargs	__class__r   r   r      s    z"SentinelManagedConnection.__init__c                 C   s<   | j }dt| j|jf }| jr8d| j| jf }|| }|S )Nz%s<service=%s%%s>z,host=%s,port=%s)r   typer   service_namehostport)r   poolsZ	host_infor   r   r   __repr__   s    z"SentinelManagedConnection.__repr__c                    sH   |\| _ | _tt|   | jjrD| d t| 	 dkrDt
dd S )NZPINGZPONGzPING failed)r   r    r   r   connectr   check_connectionZsend_commandr
   read_responser   )r   addressr   r   r   
connect_to    s    
z$SentinelManagedConnection.connect_toc              	   C   sd   | j r
d S | jjr$| | j  n<| j D ],}z| |W   S  tyX   Y q.Y q.0 q.td S N)_sockr   	is_masterr(   get_master_addressrotate_slavesr   r   )r   slaver   r   r   r$   (   s    z!SentinelManagedConnection.connectc                    sB   zt t|  W S  ty<   | jjr6|   td Y n0 d S )Nz"The previous master is now a slave)r   r   r&   r   r   r+   
disconnectr   r   r   r   r   r&   5   s    z'SentinelManagedConnection.read_response)	r   r   r   r   r#   r(   r$   r&   __classcell__r   r   r   r   r      s
   r   c                       sP   e Zd ZdZ fddZdd Z fddZ fdd	Zd
d Zdd Z	  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                    sb   | dt|d< |dd| _|dd| _tt| jf i | t	| | j
d< || _|| _d S )NZconnection_classr+   Tr%   Fr   )getr   r   r+   r%   r   r2   r   weakrefproxyconnection_kwargsr   sentinel_manager)r   r   r7   r   r   r   r   r   L   s    zSentinelConnectionPool.__init__c                 C   s    dt | j| j| jrdpdf S )Nz%s<service=%s(%s)Zmasterr.   )r   r   r   r+   r0   r   r   r   r#   V   s
    zSentinelConnectionPool.__repr__c                    s   t t|   d | _d | _d S r)   )r   r2   resetmaster_addressslave_rr_counterr0   r   r   r   r8   ]   s    zSentinelConnectionPool.resetc                    s8   | j  p| j o| j|j|jfk}tt| }|o6||S r)   )r+   r9   r   r    r   r2   owns_connection)r   
connectioncheckparentr   r   r   r;   b   s    
z&SentinelConnectionPool.owns_connectionc                 C   s4   | j | j}| jr0| j|kr0|| _| jdd |S )NF)Zinuse_connections)r7   discover_masterr   r+   r9   r/   )r   r9   r   r   r   r,   i   s    
z)SentinelConnectionPool.get_master_addressc                 c   s   | j | j}|rh| jdu r2tdt|d | _tt|D ](}| jd t| | _|| j }|V  q>z|  V  W n t	y   Y n0 t
d| j dS )zRound-robin slave balancerNr      zNo slave found for %r)r7   discover_slavesr   r:   randomrandintlenr   r,   r   r   )r   slaves_r.   r   r   r   r-   t   s    

z$SentinelConnectionPool.rotate_slaves)r   r   r   __doc__r   r#   r8   r;   r,   r-   r1   r   r   r   r   r2   D   s   
r2   c                   @   s^   e Zd ZdZdddZdd Zdd	 Zd
d Zdd Zdd Z	e
efddZe
efd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                    sD   |d u rdd t |D }| _ fdd|D  _| _| _d S )Nc                 S   s    i | ]\}}| d r||qS )Zsocket_)
startswith).0kvr   r   r   
<dictcomp>   s   
z%Sentinel.__init__.<locals>.<dictcomp>c                    s$   g | ]\}}t ||fi  jqS r   )r   sentinel_kwargs)rJ   hostnamer    r0   r   r   
<listcomp>   s   z%Sentinel.__init__.<locals>.<listcomp>)r	   rN   	sentinelsmin_other_sentinelsr6   )r   rQ   rR   rN   r6   r   r0   r   r      s    
zSentinel.__init__c                 C   sJ   g }| j D ]&}|d|jjd |jjd f  q
dt| jd|f S )Nz%s:%sr   r    z%s<sentinels=[%s]>,)rQ   appendr   r6   r   r   join)r   Zsentinel_addressessentinelr   r   r   r#      s    



zSentinel.__repr__c                 C   s2   |d r|d s|d rdS |d | j k r.dS dS )Nr+   is_sdownis_odownFznum-other-sentinelsT)rR   )r   stater   r   r   r   check_master_state   s
    zSentinel.check_master_statec              
   C   s   t | jD ]z\}}z| }W n ttfy8   Y q
Y n0 ||}|r
| ||r
|| jd  | jd< | j|< |d |d f  S q
td|f dS )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.
        r   ipr    zNo master found for %rN)	enumeraterQ   Zsentinel_mastersr   r   r3   rZ   r   )r   r   Zsentinel_norV   ZmastersrY   r   r   r   r?      s    


zSentinel.discover_masterc                 C   s:   g }|D ],}|d s|d rq| |d |d f q|S )z1Remove slaves that are in an ODOWN or SDOWN staterX   rW   r[   r    )rT   )r   rE   Zslaves_aliver.   r   r   r   filter_slaves   s    zSentinel.filter_slavesc                 C   sR   | j D ]F}z||}W n tttfy4   Y qY n0 | |}|r|  S qg S )z;Returns a list of alive slaves for service ``service_name``)rQ   Zsentinel_slavesr   r   r   r]   )r   r   rV   rE   r   r   r   rA      s    



zSentinel.discover_slavesc                 K   s4   d|d< t | j}|| |||| fi |dS )aF  
        Returns a redis client instance for the ``service_name`` master.

        A 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 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.
        Tr+   r   dictr6   updater   r   Zredis_classZconnection_pool_classr   r6   r   r   r   
master_for   s    

zSentinel.master_forc                 K   s4   d|d< t | j}|| |||| fi |d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 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_   rb   r   r   r   	slave_for  s    

zSentinel.slave_for)r   N)r   r   r   rG   r   r#   rZ   r?   r]   rA   r   r2   rc   rd   r   r   r   r   rH      s   
	
rH   )rB   r4   Zredis.clientr   Zredis.connectionr   r   Zredis.exceptionsr   r   r   r   Zredis._compatr	   r
   r   r   r   r   r2   objectrH   r   r   r   r   <module>   s   1C