ó
Ì	g]c           @   s  d  Z  d d l Z d d l Z d d l Z d d l Z d d l m Z m Z d d l m	 Z	 m
 Z
 e j e ƒ Z d e f d „  ƒ  YZ d e j e j e j e j f d „  ƒ  YZ d	 e f d
 „  ƒ  YZ d e j f d „  ƒ  YZ d e j f d „  ƒ  YZ d e f d „  ƒ  YZ d S(   s¡   
Implementation of `nbio_interface.AbstractIOServices` on top of a
selector-based I/O loop, such as tornado's and our home-grown
select_connection's I/O loops.

iÿÿÿÿN(   t   nbio_interfacet   io_services_utils(   t   check_callback_argt   check_fd_argt   AbstractSelectorIOLoopc           B   sø   e  Z d  Z e e j d „  ƒ ƒ Z e e j d „  ƒ ƒ Z e e j d „  ƒ ƒ Z e j d „  ƒ Z	 e j d „  ƒ Z
 e j d „  ƒ Z e j d „  ƒ Z e j d „  ƒ Z e j d	 „  ƒ Z e j d
 „  ƒ Z e j d „  ƒ Z e j d „  ƒ Z RS(   s(  Selector-based I/O loop interface expected by
    `selector_ioloop_adapter.SelectorIOServicesAdapter`

    NOTE: this interface follows the corresponding methods and attributes
     of `tornado.ioloop.IOLoop` in order to avoid additional adapter layering
     when wrapping tornado's IOLoop.
    c         C   s   d S(   s  The value of the I/O loop's READ flag; READ/WRITE/ERROR may be used
        with bitwise operators as expected.

        Implementation note: the implementations can simply replace these
        READ/WRITE/ERROR properties with class-level attributes

        N(    (   t   self(    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyt   READ   s    c         C   s   d S(   sy   The value of the I/O loop's WRITE flag; READ/WRITE/ERROR may be used
        with bitwise operators as expected

        N(    (   R   (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyt   WRITE'   s    c         C   s   d S(   sy   The value of the I/O loop's ERROR flag; READ/WRITE/ERROR may be used
        with bitwise operators as expected

        N(    (   R   (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyt   ERROR/   s    c         C   s   d S(   s  Release IOLoop's resources.

        the `close()` method is intended to be called by the application or test
        code only after `start()` returns. After calling `close()`, no other
        interaction with the closed instance of `IOLoop` should be performed.

        N(    (   R   (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyt   close7   s    c         C   s   d S(   sO   Run the I/O loop. It will loop until requested to exit. See `stop()`.

        N(    (   R   (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyt   startA   s    c         C   s   d S(   s%  Request exit from the ioloop. The loop is NOT guaranteed to
        stop before this method returns.

        To invoke `stop()` safely from a thread other than this IOLoop's thread,
        call it via `add_callback_threadsafe`; e.g.,

            `ioloop.add_callback(ioloop.stop)`

        N(    (   R   (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyt   stopG   s    c         C   s   d S(   sª  Add the callback to the IOLoop timer to be called after delay seconds
        from the time of call on best-effort basis. Returns a handle to the
        timeout.

        :param float delay: The number of seconds to wait to call callback
        :param callable callback: The callback method
        :returns: handle to the created timeout that may be passed to
            `remove_timeout()`
        :rtype: object

        N(    (   R   t   delayt   callback(    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyt
   call_laterS   s    c         C   s   d S(   sV   Remove a timeout

        :param timeout_handle: Handle of timeout to remove

        N(    (   R   t   timeout_handle(    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyt   remove_timeouta   s    c         C   s   d S(   sú  Requests a call to the given function as soon as possible in the
        context of this IOLoop's thread.

        NOTE: This is the only thread-safe method in IOLoop. All other
        manipulations of IOLoop must be performed from the IOLoop's thread.

        For example, a thread may request a call to the `stop` method of an
        ioloop that is running in a different thread via
        `ioloop.add_callback_threadsafe(ioloop.stop)`

        :param callable callback: The callback method

        N(    (   R   R   (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyt   add_callbacki   s    c         C   s   d S(   s  Start watching the given file descriptor for events

        :param int fd: The file descriptor
        :param callable handler: When requested event(s) occur,
            `handler(fd, events)` will be called.
        :param int events: The event mask using READ, WRITE, ERROR.

        N(    (   R   t   fdt   handlert   events(    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyt   add_handlery   s    c         C   s   d S(   s˜   Changes the events we watch for

        :param int fd: The file descriptor
        :param int events: The event mask using READ, WRITE, ERROR

        N(    (   R   R   R   (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyt   update_handler„   s    c         C   s   d S(   sh   Stop watching the given file descriptor for events

        :param int fd: The file descriptor

        N(    (   R   R   (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyt   remove_handler   s    (   t   __name__t
   __module__t   __doc__t   propertyt   abct   abstractmethodR   R   R   R	   R
   R   R   R   R   R   R   R   (    (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyR      s    

	t   SelectorIOServicesAdapterc           B   s   e  Z d  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z	 d d d d d	 „ Z
 d
 „  Z d „  Z d „  Z d „  Z d „  Z RS(   sˆ  Implements the
    :py:class:`.nbio_interface.AbstractIOServices` interface
    on top of selector-style native loop having the
    :py:class:`AbstractSelectorIOLoop` interface, such as
    :py:class:`pika.selection_connection.IOLoop` and :py:class:`tornado.IOLoop`.

    NOTE:
    :py:class:`.nbio_interface.AbstractFileDescriptorServices`
    interface is only required by the mixins.

    c         C   sA   | |  _  t ƒ  |  _ |  j  j |  _ |  j  j |  j  j B|  _ d S(   s½   
        :param AbstractSelectorIOLoop native_loop: An instance compatible with
            the `AbstractSelectorIOLoop` interface, but not necessarily derived
            from it.
        N(   t   _loopt   dictt	   _watchersR   t   _readable_maskR   R   t   _writable_mask(   R   t   native_loop(    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyt   __init__¦   s    	c         C   s   |  j  S(   s^   Implement
        :py:meth:`.nbio_interface.AbstractIOServices.get_native_ioloop()`.

        (   R   (   R   (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyt   get_native_ioloopº   s    c         C   s   |  j  j ƒ  d S(   sJ   Implement :py:meth:`.nbio_interface.AbstractIOServices.close()`.

        N(   R   R	   (   R   (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyR	   Á   s    c         C   s   |  j  j ƒ  d S(   sH   Implement :py:meth:`.nbio_interface.AbstractIOServices.run()`.

        N(   R   R
   (   R   (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyt   runÇ   s    c         C   s   |  j  j ƒ  d S(   sI   Implement :py:meth:`.nbio_interface.AbstractIOServices.stop()`.

        N(   R   R   (   R   (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyR   Í   s    c         C   s   |  j  j | ƒ d S(   sd   Implement
        :py:meth:`.nbio_interface.AbstractIOServices.add_callback_threadsafe()`.

        N(   R   R   (   R   R   (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyt   add_callback_threadsafeÓ   s    c         C   s   t  |  j j | | ƒ |  j ƒ S(   sO   Implement :py:meth:`.nbio_interface.AbstractIOServices.call_later()`.

        (   t   _TimerHandleR   R   (   R   R   R   (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyR   Ú   s    i    c         C   sF   t  t d |  j d | d | d | d | d | d | d | ƒ j ƒ  ƒ S(	   sP   Implement :py:meth:`.nbio_interface.AbstractIOServices.getaddrinfo()`.

        R$   t   hostt   portt   familyt   socktypet   protot   flagst   on_done(   t   _SelectorIOLoopIOHandlet   _AddressResolverR   R
   (   R   R*   R+   R0   R,   R-   R.   R/   (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyt   getaddrinfoà   s    	c         C   s  t  j d | | ƒ t | ƒ t | d ƒ y |  j | } WnS t k
 r |  j j | |  j |  j	 ƒ t
 d | ƒ |  j | <t  j d | ƒ nn X| j d k rå | j d k	 sµ t ‚ |  j j | |  j	 |  j Bƒ t  j d | ƒ n t  j d | ƒ | | _ d S(   sc   Implement
        :py:meth:`.nbio_interface.AbstractFileDescriptorServices.set_reader()`.

        s,   SelectorIOServicesAdapter.set_reader(%s, %r)t   on_readablet   readers"   set_reader(%s, _) added handler Rds&   set_reader(%s, _) updated handler RdWrs"   set_reader(%s, _) replacing readerN(   t   LOGGERt   debugR   R   R!   t   KeyErrorR   R   t   _on_reader_writer_fd_eventsR"   t   _FileDescriptorCallbacksR5   t   Nonet   writert   AssertionErrorR   R#   (   R   R   R4   t	   callbacks(    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyt
   set_readerö   s$    

	c         C   s÷   t  j d | ƒ t | ƒ y |  j | } Wn" t k
 rO t  j d | ƒ t SX| j d k rˆ | j d k	 st t	 ‚ t  j d | ƒ t Sd | _ | j d k rÍ |  j | =|  j
 j | ƒ t  j d | ƒ n& |  j
 j | |  j ƒ t  j d | ƒ t S(   sf   Implement
        :py:meth:`.nbio_interface.AbstractFileDescriptorServices.remove_reader()`.

        s+   SelectorIOServicesAdapter.remove_reader(%s)s!   remove_reader(%s) neither was sets&   remove_reader(%s) reader wasn't set Wrs!   remove_reader(%s) removed handlers$   remove_reader(%s) updated handler WrN(   R6   R7   R   R!   R8   t   FalseR5   R;   R<   R=   R   R   R   R#   t   True(   R   R   R>   (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyt   remove_reader  s&    
	
c         C   s  t  j d | | ƒ t | ƒ t | d ƒ y |  j | } WnS t k
 r |  j j | |  j |  j	 ƒ t
 d | ƒ |  j | <t  j d | ƒ nn X| j d k rå | j d k	 sµ t ‚ |  j j | |  j |  j	 Bƒ t  j d | ƒ n t  j d | ƒ | | _ d S(   sc   Implement
        :py:meth:`.nbio_interface.AbstractFileDescriptorServices.set_writer()`.

        s,   SelectorIOServicesAdapter.set_writer(%s, %r)t   on_writableR<   s"   set_writer(%s, _) added handler Wrs&   set_writer(%s, _) updated handler RdWrs"   set_writer(%s, _) replacing writerN(   R6   R7   R   R   R!   R8   R   R   R9   R#   R:   R<   R;   R5   R=   R   R"   (   R   R   RC   R>   (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyt
   set_writer3  s$    

	c         C   s÷   t  j d | ƒ t | ƒ y |  j | } Wn" t k
 rO t  j d | ƒ t SX| j d k rˆ | j d k	 st t	 ‚ t  j d | ƒ t Sd | _ | j d k rÍ |  j | =|  j
 j | ƒ t  j d | ƒ n& |  j
 j | |  j ƒ t  j d | ƒ t S(   sf   Implement
        :py:meth:`.nbio_interface.AbstractFileDescriptorServices.remove_writer()`.

        s+   SelectorIOServicesAdapter.remove_writer(%s)s"   remove_writer(%s) neither was set.s&   remove_writer(%s) writer wasn't set Rds!   remove_writer(%s) removed handlers$   remove_writer(%s) updated handler RdN(   R6   R7   R   R!   R8   R@   R<   R;   R5   R=   R   R   R   R"   RA   (   R   R   R>   (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyt   remove_writerP  s&    
	
c         C   sº   |  j  | } | |  j @rE | j d k rE t j d | t | ƒ ƒ n  | |  j @rŠ | j d k	 rn | j ƒ  qŠ t j d | t | ƒ ƒ n  | |  j @r¶ | j d k	 r¶ | j ƒ  q¶ n  d S(   sä  Handle indicated file descriptor events requested via `set_reader()`
        and `set_writer()`.

        :param fd: file descriptor
        :param events: event mask using native loop's READ/WRITE/ERROR. NOTE:
            depending on the underlying poller mechanism, ERROR may be indicated
            upon certain file description state even though we don't request it.
            We ignore ERROR here since `set_reader()`/`set_writer()` don't
            request for it.
        s?   READ indicated on fd=%s, but reader callback is None; events=%ss@   WRITE indicated on fd=%s, but writer callback is None; events=%sN(	   R!   R"   R5   R;   R6   t   warningt   binR#   R<   (   R   R   R   R>   (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyR9   p  s    (   R   R   R   R%   R&   R	   R'   R   R(   R   R3   R?   RB   RD   RE   R9   (    (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyR   –   s"   							
		 		 R:   c           B   s#   e  Z d  Z d Z d d d „ Z RS(   s7   Holds reader and writer callbacks for a file descriptorR5   R<   c         C   s   | |  _  | |  _ d  S(   N(   R5   R<   (   R   R5   R<   (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyR%   ›  s    	(   s   readers   writerN(   R   R   R   t	   __slots__R;   R%   (    (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyR:   –  s   R)   c           B   s    e  Z d  Z d „  Z d „  Z RS(   sJ   This module's adaptation of `nbio_interface.AbstractTimerReference`.

    c         C   s   | |  _  | |  _ d S(   s  

        :param opaque handle: timer handle from the underlying loop
            implementation that may be passed to its `remove_timeout()` method
        :param AbstractSelectorIOLoop loop: the I/O loop instance that created
            the timeout.
        N(   t   _handleR   (   R   t   handlet   loop(    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyR%   ¦  s    	c         C   s;   |  j  d  k	 r7 |  j  j |  j ƒ d  |  _ d  |  _  n  d  S(   N(   R   R;   R   RI   (   R   (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyt   cancel±  s    	(   R   R   R   R%   RL   (    (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyR)   ¡  s   	R1   c           B   s    e  Z d  Z d „  Z d „  Z RS(   sF   This module's adaptation of `nbio_interface.AbstractIOReference`

    c         C   s   | j  |  _ d S(   sZ   
        :param subject: subject of the reference containing a `cancel()` method

        N(   RL   t   _cancel(   R   t   subject(    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyR%   ½  s    c         C   s
   |  j  ƒ  S(   s   Cancel pending operation

        :returns: False if was already done or cancelled; True otherwise
        :rtype: bool

        (   RM   (   R   (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyRL   Ä  s    (   R   R   R   R%   RL   (    (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyR1   ¸  s   	R2   c           B   s\   e  Z d  Z d Z d Z d Z d Z d „  Z d „  Z d „  Z	 d „  Z
 d	 „  Z d
 „  Z RS(   s&  Performs getaddrinfo asynchronously using a thread, then reports result
    via callback from the given I/O loop.

    NOTE: at this stage, we're using a thread per request, which may prove
    inefficient and even prohibitive if the app performs many of these
    operations concurrently.
    i    i   i   i   c	   	      C   s†   t  | d ƒ |  j |  _ d |  _ | |  _ | |  _ | |  _ | |  _ | |  _	 | |  _
 | |  _ | |  _ t j ƒ  |  _ d |  _ d S(   sŠ  

        :param AbstractSelectorIOLoop native_loop:
        :param host: `see socket.getaddrinfo()`
        :param port: `see socket.getaddrinfo()`
        :param family: `see socket.getaddrinfo()`
        :param socktype: `see socket.getaddrinfo()`
        :param proto: `see socket.getaddrinfo()`
        :param flags: `see socket.getaddrinfo()`
        :param on_done: on_done(records|BaseException) callback for reporting
            result from the given I/O loop. The single arg will be either an
            exception object (check for `BaseException`) in case of failure or
            the result returned by `socket.getaddrinfo()`.
        R0   N(   R   t   NOT_STARTEDt   _stateR;   t   _resultR   t   _hostt   _portt   _familyt	   _socktypet   _protot   _flagst   _on_donet	   threadingt   Lockt   _mutext   _threading_timer(	   R   R$   R*   R+   R,   R-   R.   R/   R0   (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyR%   Û  s    									c         C   s   d |  _ d |  _ d |  _ d S(   s   Release resources

        N(   R;   R   R\   RX   (   R   (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyt   _cleanupû  s    		c         C   s\   |  j  |  j k s! t |  j  ƒ ‚ |  j |  _  t j d |  j ƒ |  _ |  j j ƒ  t	 |  ƒ S(   s\   Start asynchronous DNS lookup.

        :rtype: nbio_interface.AbstractIOReference

        i    (
   RP   RO   R=   t   ACTIVERY   t   Timert   _resolveR\   R
   R1   (   R   (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyR
     s
    !c      	   C   s‰   |  j  z |  j |  j k r\ t j d |  j |  j ƒ |  j |  _ |  j j	 ƒ  |  j
 ƒ  t St j d |  j |  j |  j ƒ t SWd QXd S(   s„   Cancel the pending resolver

        :returns: False if was already done or cancelled; True otherwise
        :rtype: bool

        s   Canceling resolver for %s:%ssK   Ignoring _AddressResolver cancel request when not ACTIVE; (%s:%s); state=%sN(   R[   RP   R^   R6   R7   RR   RS   t   CANCELEDR\   RL   R]   RA   R@   (   R   (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyRL     s    


c         C   s¸   y4 t  j |  j |  j |  j |  j |  j |  j ƒ } Wn) t k
 r_ } t	 j
 d | ƒ | } n X| |  _ |  j @ |  j |  j k r› |  j j |  j ƒ n t	 j d |  j ƒ Wd QXd S(   sr   Call `socket.getaddrinfo()` and return result via user's callback
        function on the given I/O loop

        s   Address resolution failed: %rsB   Asynchronous getaddrinfo cancellation detected; in thread; host=%rN(   t   socketR3   RR   RS   RT   RU   RV   RW   t	   ExceptionR6   t   errorRQ   R[   RP   R^   R   R   t   _dispatch_resultR7   (   R   t   resultt   exc(    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyR`   +  s    
	
c         C   sm   |  j  |  j k rV |  j |  _  z' t j d |  j ƒ |  j |  j ƒ Wd |  j ƒ  Xn t j d |  j ƒ d S(   sy   This is called from the user's I/O loop to pass the result to the
         user via the user's on_done callback

        s@   Invoking asynchronous getaddrinfo() completion callback; host=%rNsL   Asynchronous getaddrinfo cancellation detected; in I/O loop context; host=%r(	   RP   R^   t	   COMPLETEDR6   R7   RR   RX   RQ   R]   (   R   (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyRe   D  s    
(   R   R   R   RO   R^   Ra   Rh   R%   R]   R
   RL   R`   Re   (    (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyR2   Î  s   	 				(   R   R   t   loggingRb   RY   t   pika.adapters.utilsR    R   t%   pika.adapters.utils.io_services_utilsR   R   t	   getLoggerR   R6   t   objectR   t   SocketConnectionMixint   StreamingConnectionMixint   AbstractIOServicest   AbstractFileDescriptorServicesR   R:   t   AbstractTimerReferenceR)   t   AbstractIOReferenceR1   R2   (    (    (    sP   /srv/kernel/kteam-tools/dashboard/pika/adapters/utils/selector_ioloop_adapter.pyt   <module>   s    ƒ	ý