o
    ݭh0                     @   s   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 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ZdS )    N)AsyncIteratorIterableMappingSequenceTupleType)Redis)
ConnectionConnectionPool
EncodableTSSLConnection)ConnectionErrorReadOnlyErrorResponseErrorTimeoutError)str_if_bytesc                   @      e Zd ZdS )MasterNotFoundErrorN__name__
__module____qualname__ r   r   V/var/www/html/stock_analysis/be/venv/lib/python3.10/site-packages/aioredis/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                    sH   | d| _| ddstt| jdi | d S t jdi | d S )Nconnection_poolsslFr   )popr   superr   __init__)selfkwargs	__class__r   r   r!      s   z"SentinelManagedConnection.__init__c                 C   sD   | j }| jj d|j }| jrd| j d| j }||7 }|d S )N	<service=z,host=z,port=>)r   r%   r   service_namehostport)r"   pools	host_infor   r   r   __repr__"   s   z"SentinelManagedConnection.__repr__c                    s\   |\| _ | _t  I d H  | jjr*| dI d H  t|  I d H dkr,t	dd S d S )NPINGPONGzPING failed)
r)   r*   r    connectr   check_connectionsend_commandr   read_responser   )r"   addressr$   r   r   
connect_to*   s   z$SentinelManagedConnection.connect_toc              	      sz   | j rd S | jjr| | j I d H I d H  d S | j 2 z3 d H W }z| |I d H W   S  ty9   Y qw 6 tN)_readerr   	is_masterr6   get_master_addressrotate_slavesr   r   )r"   slaver   r   r   r1   2   s    z!SentinelManagedConnection.connectc                    sD   z	t   I d H W S  ty!   | jjr |  I d H  td w )Nz"The previous master is now a slave)r    r4   r   r   r9   
disconnectr   r"   r$   r   r   r4   ?   s   z'SentinelManagedConnection.read_response)	r   r   r   r!   r.   r6   r1   r4   __classcell__r   r   r$   r   r      s    	r   c                       s\   e Zd ZdZ fddZdd Z fddZdef fd	d
Zdd Z	de
f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                    sj   | dt|d< |dd| _|dd| _t jdi | t| | j	d< || _
|| _d | _d | _d S )Nconnection_classr9   Tr2   Fr   r   )getr   r   r9   r2   r    r!   weakrefproxyconnection_kwargsr(   sentinel_managermaster_addressslave_rr_counter)r"   r(   rF   r#   r$   r   r   r!   V   s   
zSentinelConnectionPool.__init__c                 C   s&   | j j d| j d| jrdpd dS )Nr&   (masterr<   z)>)r%   r   r(   r9   r>   r   r   r   r.   c   s   
zSentinelConnectionPool.__repr__c                    s   t    d | _d | _d S r7   )r    resetrG   rH   r>   r$   r   r   rK   i   s   

zSentinelConnectionPool.reset
connectionc                    s0   | j  p| j o| j|j|jfk}|ot |S r7   )r9   rG   r)   r*   r    owns_connection)r"   rL   checkr$   r   r   rM   n   s   z&SentinelConnectionPool.owns_connectionc                    sB   | j | jI d H }| jr| j|kr|| _| jddI d H  |S )NF)inuse_connections)rF   discover_masterr(   r9   rG   r=   )r"   rG   r   r   r   r:   t   s   
z)SentinelConnectionPool.get_master_addressreturnc                 C  s   | j | jI dH }|r8| jdu rtdt|d | _tt|D ]}| jd t| | _|| j }|V  q#z
|  I dH V  W n	 t	yK   Y nw t
d| j)zRound-robin slave balancerNr      zNo slave found for )rF   discover_slavesr(   rH   randomrandintlenranger:   r   r   )r"   slaves_r<   r   r   r   r;   ~   s   

z$SentinelConnectionPool.rotate_slaves)r   r   r   __doc__r!   r.   rK   r	   rM   r:   r   r;   r?   r   r   r$   r   r@   N   s    
r@   c                   @   s   e Zd ZdZ		dddZdd Zded	ed
efddZ	d	efddZ
dee d
eeeef  fddZd	ed
eeeef  fddZeefd	edee dee fddZeefd	edee dee fddZdS )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.
    r   Nc                    sD   |d u rdd |  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 d||d  jqS ))r)   r*   r   )r   sentinel_kwargs)r^   hostnamer*   r>   r   r   
<listcomp>   s    z%Sentinel.__init__.<locals>.<listcomp>)itemsrb   	sentinelsmin_other_sentinelsrE   )r"   rf   rg   rb   rE   r   r>   r   r!      s   	

zSentinel.__init__c                 C   sN   g }| j D ]}||jjd  d|jjd   q| jj dd| dS )Nr)   :r*   z<sentinels=[,z]>)rf   appendr   rE   r%   r   join)r"   sentinel_addressessentinelr   r   r   r.      s   

zSentinel.__repr__stater(   rQ   c                 C   s2   |d r|d s|d rdS |d | j k rdS dS )Nr9   is_sdownis_odownFznum-other-sentinelsT)rg   )r"   rn   r(   r   r   r   check_master_state   s
   zSentinel.check_master_statec              
      s   t | jD ]>\}}z	| I dH }W n ttfy   Y qw ||}|rD| ||rD|| jd | jd< | j|< |d |d f  S q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.
        Nr   ipr*   zNo master found for )	enumeraterf   sentinel_mastersr   r   rB   rq   r   )r"   r(   sentinel_norm   mastersrn   r   r   r   rP      s   
zSentinel.discover_masterrX   c                 C   s:   g }|D ]}|d s|d rq| |d |d f q|S )z1Remove slaves that are in an ODOWN or SDOWN staterp   ro   rr   r*   )rj   )r"   rX   slaves_aliver<   r   r   r   filter_slaves   s   zSentinel.filter_slavesc                    sV   | j D ]$}z
||I dH }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``N)rf   sentinel_slavesr   r   r   rx   )r"   r(   rm   rX   r   r   r   rS      s   

zSentinel.discover_slavesredis_classconnection_pool_classc                 K   4   d|d< t | j}|| |||| fi |d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.
        Tr9   r   dictrE   updater"   r(   rz   r{   r#   rE   r   r   r   
master_for  s   

zSentinel.master_forc                 K   r|   )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.
        Fr9   r}   r~   r   r   r   r   	slave_for*  s   

zSentinel.slave_for)r   N)r   r   r   rZ   r!   r.   r   strboolrq   rP   r   r   r   r   r   rx   rS   r   r@   r   r   r   r   r   r   r   r[      sH    
	


)r[   )rT   rC   typingr   r   r   r   r   r   aioredis.clientr   aioredis.connectionr	   r
   r   r   aioredis.exceptionsr   r   r   r   aioredis.utilsr   r   r   r   r@   r[   r   r   r   r   <module>   s     6B