ó
O'—^c        	   @@  sš  d  Z  d d l m Z d d l Z 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 d d l m Z m Z m Z d d	 l m Z d
 d l m Z m Z d
 d l m Z d
 d l m Z d
 d l m Z d
 d l m Z y d d l m  Z  WnI e! k
 r[y d d l" m  Z  Wq\e! k
 rWd d l# m  Z  q\Xn Xd d d d d d d d d g	 Z$ d Z% e e& ƒ Z' d a) d „  Z* d „  Z+ d „  Z, d e f d „  ƒ  YZ- d „  Z. d e/ d  „ Z0 d! „  Z1 d" „  Z2 d
 d d d# „ Z3 d
 d d d$ „ Z4 d d e/ d% „ Z5 d e/ d d& „ Z6 d' „  Z7 d( „  Z8 e	 d) „  ƒ Z9 d d* „ Z: d d+ „ Z; d d d, „ Z< d- e= f d. „  ƒ  YZ> d S(/   s/   
kombu.common
============

Common Utilities.

i    (   t   absolute_importN(   t   deque(   t   contextmanager(   t   partial(   t   count(   t   uuid4t   uuid3t   NAMESPACE_OID(   t   RecoverableConnectionErrori   (   t   Exchanget   Queue(   t   range(   t
   get_logger(   t   registry(   t   uuid(   t	   get_identt	   Broadcastt   maybe_declareR   t   itermessagest
   send_replyt   collect_repliest   insuredt   drain_consumert	   eventloopiÿÿ  c           C@  s   t  d  k r t ƒ  j a  n  t  S(   N(   t   _node_idt   NoneR   t   int(    (    (    s.   /tmp/pip-unpacked-wheel-UAnTfW/kombu/common.pyt   get_node_id1   s    c         C@  s/   d |  | | t  | ƒ f } t t t | ƒ ƒ S(   Ns   %x-%x-%x-%x(   t   idt   strR   R   (   t   node_idt
   process_idt	   thread_idt   instancet   ent(    (    s.   /tmp/pip-unpacked-wheel-UAnTfW/kombu/common.pyt   generate_oid8   s    c         C@  s   t  t ƒ  t j ƒ  t ƒ  |  ƒ S(   N(   R#   R   t   ost   getpidR   (   R!   (    (    s.   /tmp/pip-unpacked-wheel-UAnTfW/kombu/common.pyt   oid_from=   s    c           B@  s3   e  Z d  Z e j d Z d d e d d d „ Z RS(   só  Convenience class used to define broadcast queues.

    Every queue instance will have a unique name,
    and both the queue and exchange is configured with auto deletion.

    :keyword name: This is used as the name of the exchange.
    :keyword queue: By default a unique id is used for the queue
       name for every consumer.  You can specify a custom queue
       name here.
    :keyword \*\*kwargs: See :class:`~kombu.Queue` for a list
        of additional keyword arguments supported.

    t   queuec         K@  sn   | p d t  ƒ  f } t t |  ƒ j d | p1 | d | d | d | d | d  k	 rX | n t | d d ƒ|  S(	   Ns   bcast.%st   aliasR'   t   namet   auto_deletet   exchanget   typet   fanout(   R   t   superR   t   __init__R   R	   (   t   selfR)   R'   R*   R+   R(   t   kwargs(    (    s.   /tmp/pip-unpacked-wheel-UAnTfW/kombu/common.pyR/   Q   s    N(   R'   N(   (   R'   N(   t   __name__t
   __module__t   __doc__R
   t   attrsR   t   TrueR/   (    (    (    s.   /tmp/pip-unpacked-wheel-UAnTfW/kombu/common.pyR   A   s   	c         C@  s   |  | j  j j k S(   N(   t
   connectiont   clientt   declared_entities(   t   entityt   channel(    (    s.   /tmp/pip-unpacked-wheel-UAnTfW/kombu/common.pyt   declaration_cached_   s    c         K@  sÊ   |  j  } | s- | s t ‚ |  j | ƒ }  n  | d  k rQ | sE t ‚ |  j } n  d  } } | j r› |  j r› | j j j } t	 |  ƒ } | | k r› t
 Sn  | r· t |  | | | |  St |  | | | ƒ S(   N(   t   is_boundt   AssertionErrort   bindR   R;   R7   t   can_cache_declarationR8   R9   t   hasht   Falset   _imaybe_declaret   _maybe_declare(   R:   R;   t   retryt   retry_policyR=   t   declaredt   ident(    (    s.   /tmp/pip-unpacked-wheel-UAnTfW/kombu/common.pyR   c   s"    	

c         C@  sW   | p |  j  } | j s' t d ƒ ‚ n  |  j ƒ  | d  k	 rS | rS | j | ƒ n  t S(   Ns   channel disconnected(   R;   R7   R   t   declareR   t   addR6   (   R:   RG   RH   R;   (    (    s.   /tmp/pip-unpacked-wheel-UAnTfW/kombu/common.pyRD   {   s    	
c         K@  s+   |  j  j j j |  t |  |  | | | ƒ S(   N(   R;   R7   R8   t   ensureRD   (   R:   RG   RH   R;   RF   (    (    s.   /tmp/pip-unpacked-wheel-UAnTfW/kombu/common.pyRC   …   s    c         #@  s”   t  ƒ  ‰  ‡  f d †  } | g | p' g  |  _ |  Z xR t |  j j j d | d | d t ƒD]) } y ˆ  j ƒ  VWq] t k
 r… q] Xq] WWd  QXd  S(   Nc         @  s   ˆ  j  |  | f ƒ d  S(   N(   t   append(   t   bodyt   message(   t   acc(    s.   /tmp/pip-unpacked-wheel-UAnTfW/kombu/common.pyt
   on_messageŽ   s    t   limitt   timeoutt   ignore_timeouts(	   R   t	   callbacksR   R;   R7   R8   R6   t   popleftt
   IndexError(   t   consumerRQ   RR   RT   RP   t   _(    (   RO   s.   /tmp/pip-unpacked-wheel-UAnTfW/kombu/common.pyR   ‹   s    	c         K@  s4   t  |  j d | g d | |  d | d | d | ƒS(   Nt   queuesR;   RQ   RR   RT   (   R   t   Consumer(   t   connR;   R'   RQ   RR   RT   R1   (    (    s.   /tmp/pip-unpacked-wheel-UAnTfW/kombu/common.pyR   œ   s    c         c@  si   xb | r t  | ƒ p t ƒ  D]E } y |  j d | ƒ VWq t j k
 r` | ra | ra ‚  qa q Xq Wd S(   sá  Best practice generator wrapper around ``Connection.drain_events``.

    Able to drain events forever, with a limit, and optionally ignoring
    timeout errors (a timeout of 1 is often used in environments where
    the socket can get "stuck", and is a best practice for Kombu consumers).

    **Examples**

    ``eventloop`` is a generator::

        from kombu.common import eventloop

        def run(connection):
            it = eventloop(connection, timeout=1, ignore_timeouts=True)
            next(it)   # one event consumed, or timed out.

            for _ in eventloop(connection, timeout=1, ignore_timeouts=True):
                pass  # loop forever.

    It also takes an optional limit parameter, and timeout errors
    are propagated by default::

        for _ in eventloop(connection, limit=1, timeout=1):
            pass

    .. seealso::

        :func:`itermessages`, which is an event loop bound to one or more
        consumers, that yields any messages received.

    RR   N(   R   R   t   drain_eventst   socketRR   (   R[   RQ   RR   RS   t   i(    (    s.   /tmp/pip-unpacked-wheel-UAnTfW/kombu/common.pyR   ¤   s     "c         K@  sk   | j  | d |  d | d | t i | j d d 6| j j d ƒ d 6t j | j d 6| j d 6|  d	 S(
   sL  Send reply for request.

    :param exchange: Reply exchange
    :param req: Original request, a message with a ``reply_to`` property.
    :param producer: Producer instance
    :param retry: If true must retry according to ``reply_policy`` argument.
    :param retry_policy: Retry settings.
    :param props: Extra properties

    R+   RE   RF   t   reply_tot   routing_keyt   correlation_idt
   serializert   content_encodingN(   t   publisht   dictt
   propertiest   gett   serializerst   type_to_namet   content_typeRc   (   R+   t   reqt   msgt   producerRE   RF   t   props(    (    s.   /tmp/pip-unpacked-wheel-UAnTfW/kombu/common.pyR   Ì   s    	c   	      o@  s„   | j  d t ƒ } t } zK xD t |  | | | | Ž D]* \ } } | sS | j ƒ  n  t } | Vq4 WWd | r | j | j ƒ n  Xd S(   s+   Generator collecting replies from ``queue``t   no_ackN(   t
   setdefaultR6   RB   R   t   ackt   after_reply_message_receivedR)   (	   R[   R;   R'   t   argsR1   Ro   t   receivedRM   RN   (    (    s.   /tmp/pip-unpacked-wheel-UAnTfW/kombu/common.pyR   ã   s    c         C@  s   t  j d |  | d t ƒd  S(   Ns#   Connection error: %r. Retry in %ss
t   exc_info(   t   loggert   errorR6   (   t   exct   interval(    (    s.   /tmp/pip-unpacked-wheel-UAnTfW/kombu/common.pyt   _ensure_errbackó   s    c         c@  s+   y	 d  VWn |  j  |  j k
 r& n Xd  S(   N(   t   connection_errorst   channel_errors(   R[   (    (    s.   /tmp/pip-unpacked-wheel-UAnTfW/kombu/common.pyt   _ignore_errorsú   s    	c         O@  s3   | r) t  |  ƒ  | | | Ž  SWd QXn  t  |  ƒ S(   sà  Ignore connection and channel errors.

    The first argument must be a connection object, or any other object
    with ``connection_error`` and ``channel_error`` attributes.

    Can be used as a function:

    .. code-block:: python

        def example(connection):
            ignore_errors(connection, consumer.channel.close)

    or as a context manager:

    .. code-block:: python

        def example(connection):
            with ignore_errors(connection):
                consumer.channel.close()


    .. note::

        Connection and channel errors should be properly handled,
        and not ignored.  Using this function is only acceptable in a cleanup
        phase, like when a connection is lost or at shutdown.

    N(   R}   (   R[   t   funRs   R1   (    (    s.   /tmp/pip-unpacked-wheel-UAnTfW/kombu/common.pyt   ignore_errors  s    c         C@  s   | r | | ƒ n  d  S(   N(    (   R7   R;   t	   on_revive(    (    s.   /tmp/pip-unpacked-wheel-UAnTfW/kombu/common.pyt   revive_connection%  s    c         K@  sŸ   | p	 t  } |  j d t ƒ { } | j d | ƒ | j } t t | d | ƒ}	 | j | | d | d |	 | }
 |
 | t | d | ƒŽ  \ } } | SWd QXd S(   sc   Ensures function performing broker commands completes
    despite intermittent connection failures.t   blockt   errbackR€   R7   N(	   Rz   t   acquireR6   t   ensure_connectiont   default_channelR   R   t	   autoretryRe   (   t   poolR~   Rs   R1   Rƒ   R€   t   optsR[   R;   t   reviveR   t   retvalRX   (    (    s.   /tmp/pip-unpacked-wheel-UAnTfW/kombu/common.pyR   *  s    	!t   QoSc           B@  sG   e  Z d  Z d Z d „  Z d d „ Z d d „ Z d „  Z d „  Z	 RS(   sã  Thread safe increment/decrement of a channels prefetch_count.

    :param callback: Function used to set new prefetch count,
        e.g. ``consumer.qos`` or ``channel.basic_qos``.  Will be called
        with a single ``prefetch_count`` keyword argument.
    :param initial_value: Initial prefetch count value.

    **Example usage**

    .. code-block:: python

        >>> from kombu import Consumer, Connection
        >>> connection = Connection('amqp://')
        >>> consumer = Consumer(connection)
        >>> qos = QoS(consumer.qos, initial_prefetch_count=2)
        >>> qos.update()  # set initial

        >>> qos.value
        2

        >>> def in_some_thread():
        ...     qos.increment_eventually()

        >>> def in_some_other_thread():
        ...     qos.decrement_eventually()

        >>> while 1:
        ...    if qos.prev != qos.value:
        ...        qos.update()  # prefetch changed so update.

    It can be used with any function supporting a ``prefetch_count`` keyword
    argument::

        >>> channel = connection.channel()
        >>> QoS(channel.basic_qos, 10)


        >>> def set_qos(prefetch_count):
        ...     print('prefetch count now: %r' % (prefetch_count, ))
        >>> QoS(set_qos, 10)

    c         C@  s+   | |  _  t j ƒ  |  _ | p! d |  _ d  S(   Ni    (   t   callbackt	   threadingt   RLockt   _mutext   value(   R0   R   t   initial_value(    (    s.   /tmp/pip-unpacked-wheel-UAnTfW/kombu/common.pyR/   h  s    	i   c         C@  s<   |  j  * |  j r/ |  j t | d ƒ |  _ n  Wd QX|  j S(   s¡   Increment the value, but do not update the channels QoS.

        The MainThread will be responsible for calling :meth:`update`
        when necessary.

        i    N(   R   R‘   t   max(   R0   t   n(    (    s.   /tmp/pip-unpacked-wheel-UAnTfW/kombu/common.pyt   increment_eventuallym  s    
	"c         C@  sM   |  j  ; |  j r@ |  j | 8_ |  j d k  r@ d |  _ q@ n  Wd QX|  j S(   s¡   Decrement the value, but do not update the channels QoS.

        The MainThread will be responsible for calling :meth:`update`
        when necessary.

        i   N(   R   R‘   (   R0   R”   (    (    s.   /tmp/pip-unpacked-wheel-UAnTfW/kombu/common.pyt   decrement_eventuallyy  s    
	c         C@  sj   | |  j  k rf | } | t k r: t j d t ƒ d } n  t j d | ƒ |  j d | ƒ | |  _  n  | S(   s#   Set channel prefetch_count setting.s(   QoS: Disabled: prefetch_count exceeds %ri    s   basic.qos: prefetch_count->%st   prefetch_count(   t   prevt   PREFETCH_COUNT_MAXRv   t   warnt   debugR   (   R0   t   pcountt	   new_value(    (    s.   /tmp/pip-unpacked-wheel-UAnTfW/kombu/common.pyt   set‡  s    		c         C@  s$   |  j   |  j |  j ƒ SWd QXd S(   s)   Update prefetch count with current value.N(   R   Rž   R‘   (   R0   (    (    s.   /tmp/pip-unpacked-wheel-UAnTfW/kombu/common.pyt   update”  s    
N(
   R2   R3   R4   R   R˜   R/   R•   R–   Rž   RŸ   (    (    (    s.   /tmp/pip-unpacked-wheel-UAnTfW/kombu/common.pyRŒ   ;  s   *		(?   R4   t
   __future__R    R$   R]   RŽ   t   collectionsR   t
   contextlibR   t	   functoolsR   t	   itertoolsR   R   R   R   R   t   amqpR   R:   R	   R
   t   fiveR   t   logR   t   serializationR   Rh   t   utilst   _threadR   t   ImportErrort   threadt   dummy_threadt   __all__R™   R2   Rv   R   R   R   R#   R&   R   R<   RB   R   RD   RC   R   R   R   R   R   Rz   R}   R   R   R   t   objectRŒ   (    (    (    s.   /tmp/pip-unpacked-wheel-UAnTfW/kombu/common.pyt   <module>   sb   								
	)		#