o
    svXj¾-  ã                   @   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                   @   ó   e Zd ZdS )ÚMasterNotFoundErrorN©Ú__name__Ú
__module__Ú__qualname__© r   r   úK/var/www/html/myproject/venv/lib/python3.10/site-packages/redis/sentinel.pyr      ó    r   c                   @   r   )ÚSlaveNotFoundErrorNr   r   r   r   r   r      r   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di |¤Ž d S )NÚconnection_poolr   )Úpopr   Úsuperr   Ú__init__)ÚselfÚkwargs©Ú	__class__r   r   r      s   z"SentinelManagedConnection.__init__c                 C   s<   | j }dt| ƒj|jf }| jrd| j| jf }|| }|S )Nz%s<service=%s%%s>z,host=%s,port=%s)r   Útyper   Úservice_nameÚhostÚport)r   ÚpoolÚsÚ	host_infor   r   r   Ú__repr__   s   z"SentinelManagedConnection.__repr__c                    sL   |\| _ | _tt| ƒ ¡  | jjr"|  d¡ t|  	¡ ƒdkr$t
dƒ‚d S d S )NÚPINGÚPONGzPING failed)r!   r"   r   r   Úconnectr   Úcheck_connectionÚsend_commandr
   Úread_responser   )r   Úaddressr   r   r   Ú
connect_to    s   
ýz$SentinelManagedConnection.connect_toc              	   C   s\   | j rd S | jjr|  | j ¡ ¡ d S | j ¡ D ]}z|  |¡W   S  ty+   Y qw t‚©N)Ú_sockr   Ú	is_masterr.   Úget_master_addressÚrotate_slavesr   r   )r   Úslaver   r   r   r)   (   s   ÿz!SentinelManagedConnection.connectc                    s:   zt t| ƒ ¡ W S  ty   | jjr|  ¡  tdƒ‚‚ w )Nz"The previous master is now a slave)r   r   r,   r   r   r1   Ú
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di |¤Ž t 	| ¡| j
d< || _|| _d S )NÚconnection_classr1   Tr*   Fr   r   )Úgetr   r   r1   r*   r   r8   r   ÚweakrefÚproxyÚconnection_kwargsr    Úsentinel_manager)r   r    r>   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)Úmasterr4   )r   r   r    r1   r6   r   r   r   r&   V   s
   ýzSentinelConnectionPool.__repr__c                    s   t t| ƒ ¡  d | _d | _d S r/   )r   r8   ÚresetÚmaster_addressÚslave_rr_counterr6   r   r   r   r@   ]   s   
zSentinelConnectionPool.resetc                    s8   | j  p| j o| j|j|jfk}tt| ƒ}|o| |¡S r/   )r1   rA   r!   r"   r   r8   Úowns_connection)r   Ú
connectionÚcheckÚparentr   r   r   rC   b   s   þ
z&SentinelConnectionPool.owns_connectionc                 C   s4   | j  | j¡}| jr| j|kr|| _| jdd� |S )NF)Úinuse_connections)r>   Údiscover_masterr    r1   rA   r5   )r   rA   r   r   r   r2   i   s   ÿ
z)SentinelConnectionPool.get_master_addressc                 c   sš   � | j  | j¡}|r5| jdu rt dt|ƒd ¡| _tt|ƒƒD ]}| jd t|ƒ | _|| j }|V  q z|  ¡ V  W n	 t	yE   Y nw t
d| j ƒ‚)zRound-robin slave balancerNr   é   zNo slave found for %r)r>   Údiscover_slavesr    rB   ÚrandomÚrandintÚlenr   r2   r   r   )r   ÚslavesÚ_r4   r   r   r   r3   t   s    €
ÿ
ÿz$SentinelConnectionPool.rotate_slaves)r   r   r   Ú__doc__r   r&   r@   rC   r2   r3   r7   r   r   r   r   r8   D   s    
r8   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 )Ú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)rT   Úhostnamer"   r6   r   r   Ú
<listcomp>°   s    ÿz%Sentinel.__init__.<locals>.<listcomp>)r	   rX   Ú	sentinelsÚmin_other_sentinelsr=   )r   r[   r\   rX   r=   r   r6   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]>ú,)r[   Úappendr   r=   r   r   Újoin)r   Ú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 )Nr1   Úis_sdownÚis_odownFznum-other-sentinelsT)r\   )r   Ústater    r   r   r   Úcheck_master_stateÀ   s
   zSentinel.check_master_statec              
   C   s�   t | jƒD ];\}}z| ¡ }W n ttfy   Y qw | |¡}|r@|  ||¡r@|| jd | jd< | j|< |d |d f  S qtd|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.
        r   Úipr"   zNo master found for %r)Ú	enumerater[   Úsentinel_mastersr   r   r:   re   r   )r   r    Úsentinel_nora   Úmastersrd   r   r   r   rH   È   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 staterc   rb   rf   r"   )r^   )r   rN   Úslaves_aliver4   r   r   r   Úfilter_slavesÝ   s   zSentinel.filter_slavesc                 C   sN   | j D ]!}z| |¡}W n tttfy   Y qw |  |¡}|r$|  S qg S )z;Returns a list of alive slaves for service ``service_name``)r[   Úsentinel_slavesr   r   r   rl   )r   r    ra   rN   r   r   r   rJ   æ   s   
ÿ
ÿzSentinel.discover_slavesc                 K   ó4   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.
        Tr1   ©r   ©Údictr=   Úupdate©r   r    Úredis_classÚconnection_pool_classr   r=   r   r   r   Ú
master_forò   s   

ÿ
ÿzSentinel.master_forc                 K   rn   )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.
        Fr1   ro   rp   rs   r   r   r   Ú	slave_for  s   

ÿ
ÿzSentinel.slave_for)r   N)r   r   r   rP   r   r&   re   rH   rl   rJ   r   r8   rv   rw   r   r   r   r   rQ   ‡   s    
	
ÿÿrQ   )rK   r;   Úredis.clientr   Úredis.connectionr   r   Úredis.exceptionsr   r   r   r   Úredis._compatr	   r
   r   r   r   r   r8   ÚobjectrQ   r   r   r   r   Ú<module>   s    1C