ó
O'—^c           @   sô   d  d l  Z  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 d  d l m Z m Z m Z d e	 f d „  ƒ  YZ d e	 f d	 „  ƒ  YZ d
 e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d S(   iÿÿÿÿN(   t   StrictRedis(   t   ConnectionPoolt
   Connection(   t   ConnectionErrort   ResponseErrort   ReadOnlyError(   t	   iteritemst	   nativestrt   xranget   MasterNotFoundErrorc           B   s   e  Z RS(    (   t   __name__t
   __module__(    (    (    s0   /tmp/pip-unpacked-wheel-5e_doG/redis/sentinel.pyR	      s   t   SlaveNotFoundErrorc           B   s   e  Z RS(    (   R
   R   (    (    (    s0   /tmp/pip-unpacked-wheel-5e_doG/redis/sentinel.pyR      s   t   SentinelManagedConnectionc           B   s5   e  Z d  „  Z d „  Z d „  Z d „  Z d „  Z RS(   c         K   s,   | j  d ƒ |  _ t t |  ƒ j |   d  S(   Nt   connection_pool(   t   popR   t   superR   t   __init__(   t   selft   kwargs(    (    s0   /tmp/pip-unpacked-wheel-5e_doG/redis/sentinel.pyR      s    c         C   sU   |  j  } d t |  ƒ j | j f } |  j rQ d |  j |  j f } | | } n  | S(   Ns   %s<service=%s%%s>s   ,host=%s,port=%s(   R   t   typeR
   t   service_namet   hostt   port(   R   t   poolt   st	   host_info(    (    s0   /tmp/pip-unpacked-wheel-5e_doG/redis/sentinel.pyt   __repr__   s    		c         C   sl   | \ |  _  |  _ t t |  ƒ j ƒ  |  j j rh |  j d ƒ t |  j	 ƒ  ƒ d k rh t
 d ƒ ‚ qh n  d  S(   Nt   PINGt   PONGs   PING failed(   R   R   R   R   t   connectR   t   check_connectiont   send_commandR   t   read_responseR   (   R   t   address(    (    s0   /tmp/pip-unpacked-wheel-5e_doG/redis/sentinel.pyt
   connect_to    s    c         C   s~   |  j  r d  S|  j j r2 |  j |  j j ƒ  ƒ nH x? |  j j ƒ  D]. } y |  j | ƒ SWqB t k
 ro qB qB XqB Wt ‚ d  S(   N(   t   _sockR   t	   is_masterR#   t   get_master_addresst   rotate_slavesR   R   (   R   t   slave(    (    s0   /tmp/pip-unpacked-wheel-5e_doG/redis/sentinel.pyR   (   s    	c         C   sW   y t  t |  ƒ j ƒ  SWn9 t k
 rR |  j j rL |  j ƒ  t d ƒ ‚ n  ‚  n Xd  S(   Ns"   The previous master is now a slave(   R   R   R!   R   R   R%   t
   disconnectR   (   R   (    (    s0   /tmp/pip-unpacked-wheel-5e_doG/redis/sentinel.pyR!   5   s    
(   R
   R   R   R   R#   R   R!   (    (    (    s0   /tmp/pip-unpacked-wheel-5e_doG/redis/sentinel.pyR      s
   				t   SentinelConnectionPoolc           B   sD   e  Z d  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z RS(   s¸   
    Sentinel backed connection pool.

    If ``check_connection`` flag is set to True, SentinelManagedConnection
    sends a PING command right after establishing the connection.
    c         K   s‚   | j  d t ƒ | d <| j d t ƒ |  _ | j d t ƒ |  _ t t |  ƒ j	 |   t
 j |  ƒ |  j d <| |  _ | |  _ d  S(   Nt   connection_classR%   R   R   (   t   getR   R   t   TrueR%   t   FalseR   R   R*   R   t   weakreft   proxyt   connection_kwargsR   t   sentinel_manager(   R   R   R2   R   (    (    s0   /tmp/pip-unpacked-wheel-5e_doG/redis/sentinel.pyR   L   s    	c         C   s,   d t  |  ƒ j |  j |  j r$ d p' d f S(   Ns   %s<service=%s(%s)t   masterR(   (   R   R
   R   R%   (   R   (    (    s0   /tmp/pip-unpacked-wheel-5e_doG/redis/sentinel.pyR   V   s    c         C   s)   t  t |  ƒ j ƒ  d  |  _ d  |  _ d  S(   N(   R   R*   t   resett   Nonet   master_addresst   slave_rr_counter(   R   (    (    s0   /tmp/pip-unpacked-wheel-5e_doG/redis/sentinel.pyR4   ]   s    	c         C   s\   |  j  j |  j ƒ } |  j rX |  j d  k r9 | |  _ qX | |  j k rX |  j ƒ  qX n  | S(   N(   R2   t   discover_masterR   R%   R6   R5   R)   (   R   R6   (    (    s0   /tmp/pip-unpacked-wheel-5e_doG/redis/sentinel.pyR&   b   s    		c         c   sÒ   |  j  j |  j ƒ } | r˜ |  j d k rL t j d t | ƒ d ƒ |  _ n  xI t t | ƒ ƒ D]2 } |  j d t | ƒ |  _ | |  j } | Vq_ Wn  y |  j	 ƒ  VWn t
 k
 rº n Xt d |  j ƒ ‚ d S(   s   Round-robin slave balanceri    i   s   No slave found for %rN(   R2   t   discover_slavesR   R7   R5   t   randomt   randintt   lenR   R&   R	   R   (   R   t   slavest   _R(   (    (    s0   /tmp/pip-unpacked-wheel-5e_doG/redis/sentinel.pyR'   m   s    "c         C   sp   |  j  t j ƒ  k rl |  j ƒ  |  j ƒ  |  j |  j |  j d |  j d |  j	 d |  j
 d |  j |  j n  d  S(   NR%   R   R+   t   max_connections(   t   pidt   ost   getpidR)   R4   R   R   R2   R%   R   R+   R?   R1   (   R   (    (    s0   /tmp/pip-unpacked-wheel-5e_doG/redis/sentinel.pyt	   _checkpid   s    

			(	   R
   R   t   __doc__R   R   R4   R&   R'   RC   (    (    (    s0   /tmp/pip-unpacked-wheel-5e_doG/redis/sentinel.pyR*   D   s   	
				t   Sentinelc           B   sh   e  Z d  Z d d
 d „ Z d „  Z d „  Z d „  Z d „  Z d „  Z	 e
 e d „ Z e
 e d	 „ Z RS(   sq  
    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')
    '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.
    i    c   	      K   sŸ   | d  k rO t g  t | ƒ D]' \ } } | j d ƒ r | | f ^ q ƒ } n  | |  _ g  | D]! \ } } t | | |  j  ^ q_ |  _ | |  _ | |  _ d  S(   Nt   socket_(	   R5   t   dictR   t
   startswitht   sentinel_kwargsR    t	   sentinelst   min_other_sentinelsR1   (	   R   RJ   RK   RI   R1   t   kt   vt   hostnameR   (    (    s0   /tmp/pip-unpacked-wheel-5e_doG/redis/sentinel.pyR   ¨   s    '	.	c         C   se   g  } x< |  j  D]1 } | j d | j j d | j j d f ƒ q Wd t |  ƒ j d j | ƒ f S(   Ns   %s:%sR   R   s   %s<sentinels=[%s]>t   ,(   RJ   t   appendR   R1   R   R
   t   join(   R   t   sentinel_addressest   sentinel(    (    s0   /tmp/pip-unpacked-wheel-5e_doG/redis/sentinel.pyR   ¸   s    	c         C   s>   | d s | d s | d r# t  S| d |  j k  r: t  St S(   NR%   t   is_sdownt   is_odowns   num-other-sentinels(   R.   RK   R-   (   R   t   stateR   (    (    s0   /tmp/pip-unpacked-wheel-5e_doG/redis/sentinel.pyt   check_master_stateÃ   s
    c         C   s¹   xŸ t  |  j ƒ D]Ž \ } } y | j ƒ  } Wn t k
 rB q n X| j | ƒ } | r |  j | | ƒ r | |  j d |  j d <|  j | <| d | d f Sq Wt d | f ƒ ‚ d S(   sê   
        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.
        i    t   ipR   s   No master found for %rN(   t	   enumerateRJ   t   sentinel_mastersR   R,   RW   R	   (   R   R   t   sentinel_noRS   t   mastersRV   (    (    s0   /tmp/pip-unpacked-wheel-5e_doG/redis/sentinel.pyR8   Ë   s    "c         C   sP   g  } xC | D]; } | d s | d r- q n  | j  | d | d f ƒ q W| S(   s1   Remove slaves that are in an ODOWN or SDOWN stateRU   RT   RX   R   (   RP   (   R   R=   t   slaves_aliveR(   (    (    s0   /tmp/pip-unpacked-wheel-5e_doG/redis/sentinel.pyt   filter_slavesà   s    c         C   sa   xZ |  j  D]O } y | j | ƒ } Wn t t f k
 r? q
 n X|  j | ƒ } | r
 | Sq
 Wg  S(   s;   Returns a list of alive slaves for service ``service_name``(   RJ   t   sentinel_slavesR   R   R^   (   R   R   RS   R=   (    (    s0   /tmp/pip-unpacked-wheel-5e_doG/redis/sentinel.pyR9   é   s    c         K   s?   t  | d <t |  j ƒ } | j | ƒ | d | | |  |  ƒ S(   sL  
        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.StrictRedis 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.
        R%   R   (   R-   RG   R1   t   update(   R   R   t   redis_classt   connection_pool_classR   R1   (    (    s0   /tmp/pip-unpacked-wheel-5e_doG/redis/sentinel.pyt
   master_forõ   s
    
	c         K   s?   t  | d <t |  j ƒ } | j | ƒ | d | | |  |  ƒ S(   sÚ  
        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.StrictRedis 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.
        R%   R   (   R.   RG   R1   R`   (   R   R   Ra   Rb   R   R1   (    (    s0   /tmp/pip-unpacked-wheel-5e_doG/redis/sentinel.pyt	   slave_for  s
    
	N(   R
   R   RD   R5   R   R   RW   R8   R^   R9   R    R*   Rc   Rd   (    (    (    s0   /tmp/pip-unpacked-wheel-5e_doG/redis/sentinel.pyRE   ‹   s   						(   RA   R:   R/   t   redis.clientR    t   redis.connectionR   R   t   redis.exceptionsR   R   R   t   redis._compatR   R   R   R	   R   R   R*   t   objectRE   (    (    (    s0   /tmp/pip-unpacked-wheel-5e_doG/redis/sentinel.pyt   <module>   s   1G