ó
½-'Nc           @   sz  d  d l  Z  d  d l Z d  d l Z 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 d  d l 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 e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e e e f d „  ƒ  YZ d e e e f d „  ƒ  YZ d S(   iÿÿÿÿN(   t   FakeDatagramTransport(   t   succeedt   fail(   t   DNSLookupError(   t   format_objectt	   InvalidIDc           B   s   e  Z d  Z RS(   s=   Raised when an invalid ID is used with reactor.cancel_call().(   t   __name__t
   __module__t   __doc__(    (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyR      s   t   CallHookErrorc           B   s   e  Z d  Z RS(   s-   Raised when hooking on a reactor incorrectly.(   R   R   R   (    (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyR	      s   t   EventIDc           B   s   e  Z d  Z d „  Z RS(   s'   Unique identifier for an event handler.c         C   s   | |  _  | |  _ d S(   sÇ   
        @param event_type: Name of the event type handled by the handler.
        @param pair: Binary tuple C{(handler, priority)} holding the handler
            function and its priority.
        N(   t   _event_typet   _pair(   t   selft
   event_typet   pair(    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyt   __init__   s    	(   R   R   R   R   (    (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyR
      s   t   EventHandlingReactorMixinc           B   s5   e  Z d  Z d „  Z d d „ Z d „  Z d „  Z RS(   sA   Fire events identified by strings and register handlers for them.c         C   s    t  t |  ƒ j ƒ  i  |  _ d  S(   N(   t   superR   R   t   _event_handlers(   R   (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyR   '   s    i    c         C   sN   | | f } |  j  j | g  ƒ } | j | ƒ | j d d „  ƒ t | | ƒ S(   s*  Register an event handler.

        @param event_type: The name of the event type to handle.
        @param handler: The function handling the given event type.
        @param priority: The priority of the given handler function.

        @return: The L{EventID} of the registered handler.
        t   keyc         S   s   |  d S(   Ni   (    (   R   (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyt   <lambda>8   s    (   R   t
   setdefaultt   appendt   sortR
   (   R   R   t   handlert   priorityR   t   handlers(    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyt   call_on+   s
    	c         O   së   t  j d | ƒ g  } x¾ |  j j | d ƒ D]§ \ } } y6 t  j d t | ƒ | | ƒ | j | | | Ž  ƒ Wq, t k
 r­ t  j d t | ƒ | | | ƒ |  j ƒ  ‚  q, t  j d t | ƒ | | | ƒ q, Xq, Wt  j d | ƒ | S(   sc  Fire an event of a given type.

        Call all handlers registered for the given C{event_type}, in order
        of priority.

        @param event_type: The name of the event type to fire.
        @param args: Positional arguments to pass to the registered handlers.
        @param kwargs: Keyword arguments to pass to the registered handlers.
        s   Started firing %s.s#   Calling %s for %s with priority %d.sT   Keyboard interrupt while running event handler %s for event type %r with args %r %r.sA   Error running event handler %s for event type %r with args %r %r.s   Finished firing %s.(    (	   t   loggingt   debugR   t   getR   R   t   KeyboardInterruptt	   exceptiont   stop(   R   R   t   argst   kwargst   resultsR   R   (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyt   fire<   s&    
"			
	c         C   sC   t  | ƒ t k r/ |  j | j j | j ƒ n t d | ƒ ‚ d S(   sf   Unregister an event handler.

        @param id: the L{EventID} of the handler to unregister.
        s&   EventID instance expected, received %rN(   t   typeR
   R   R   t   removeR   R   (   R   t   id(    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyt   cancel_call\   s    (   R   R   R   R   R   R&   R*   (    (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyR   $   s
   		 t   ThreadedCallsReactorMixinc           B   sM   e  Z d  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z	 RS(   sC   Schedule functions for execution in the main thread or in new ones.c         C   s    t  t |  ƒ j ƒ  g  |  _ d  S(   N(   R   R+   R   t   _threaded_callbacks(   R   (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyR   j   s    c            s#   |  j  j ‡  ‡ ‡ f d †  ƒ d S(   s5   Schedule a function for execution in the main thread.c              s   ˆ ˆ ˆ  Ž  S(   N(    (    (   R$   R#   t   f(    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyR   p   s    N(   R,   R   (   R   R-   R#   R$   (    (   R$   R#   R-   s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyt   call_in_mainn   s    c         O   s&   t  j |  j | | | | | f ƒ d S(   s  
        Execute a callable object in a new separate thread.

        @param callback: A function to call in case C{f} was successful, it
            will be passed the return value of C{f}.
        @param errback: A function to call in case C{f} raised an exception,
            it will be pass a C{(type, value, traceback)} tuple giving
            information about the raised exception (see L{sys.exc_info}).

        @note: Both C{callback} and C{errback} will be executed in the
            the parent thread.
        N(   t   threadt   start_new_threadt
   _in_thread(   R   t   callbackt   errbackR-   R#   R$   (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyt   call_in_threadr   s    c   	      C   sŠ   y | | | Ž  } WnW t  k
 rl } t j ƒ  } | d  k rY |  j t j | d | ƒq† |  j | | Œ n X| r† |  j | | ƒ n  d  S(   Nt   exc_info(   t	   Exceptiont   sysR5   t   NoneR.   R   t   error(	   R   R2   R3   R-   R#   R$   t   resultt   eR5   (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyR1   ‚   s    c         C   sN   xG |  j  rI y |  j  j d ƒ ƒ  Wq t k
 rE } t j | ƒ q Xq Wd  S(   Ni    (   R,   t   popR6   R   R!   (   R   R;   (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyt   _run_threaded_callbacks   s
    c         C   s"   |  j  d |  j ƒ } | |  _ d  S(   Ng      à?(   t
   call_everyR=   t   _run_threaded_callbacks_id(   R   R)   (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyt   _hook_threaded_callbacks–   s    c         C   s   |  j  |  j ƒ d  S(   N(   R*   R?   (   R   (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyt   _unhook_threaded_callbacksš   s    (
   R   R   R   R   R.   R4   R1   R=   R@   RA   (    (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyR+   g   s   						t   UnixReactorMixinc           B   s   e  Z d  „  Z RS(   c         C   s   |  j  j | | d t ƒS(   s   Start listen on a Unix socket.t   wantPID(   t   _reactort
   listenUNIXt   True(   R   t   sockett   factory(    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyt   listen_unix    s    (   R   R   RI   (    (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyRB   ž   s   t	   ReactorIDc           B   s   e  Z d  „  Z RS(   c         C   s   | |  _  d  S(   N(   t   _timeout(   R   t   timeout(    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyR   §   s    (   R   R   R   (    (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyRJ   ¥   s   t   FakeReactorIDc           B   s   e  Z d  „  Z RS(   c         C   s   t  |  _ | |  _ d  S(   N(   RF   t   activet   _data(   R   t   data(    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyR   ­   s    	(   R   R   R   (    (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyRM   «   s   t   FakeReactorc           B   sq   e  Z d  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­   
    @ivar udp_transports: dict of {port: (protocol, transport)}
    @ivar hosts: Dict of {hostname: ip}. Users should populate this
        and L{resolve} will use it.
    c         C   sT   t  t |  ƒ j ƒ  d |  _ g  |  _ i  |  _ i  |  _ d d l m } | |  _	 d  S(   Ni    iÿÿÿÿ(   t   reactor(
   R   RQ   R   t   _current_timet   _callst   udp_transportst   hostst   twisted.internetRR   RD   (   R   RR   (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyR   º   s    				c         C   s   t  |  j ƒ S(   N(   t   floatRS   (   R   (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyt   timeÆ   s    c         O   s<   |  j  | } | | | | f } t j |  j | ƒ t | ƒ S(   N(   RS   t   bisectt   insort_leftRT   RM   (   R   t   secondsR-   R#   R$   t   scheduled_timet   call(    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyt
   call_laterÉ   s    c         C   s`   t  | ƒ t k rF | j |  j k r: |  j j | j ƒ n  t | _ n t t |  ƒ j	 | ƒ d  S(   N(
   R'   RM   RO   RT   R(   t   FalseRN   R   RQ   R*   (   R   R)   (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyR*   Ï   s
    c            s7   ‡ ‡ ‡ ‡ ‡ ‡ ‡  f d †  ‰  ˆ j  ˆ ˆ  ƒ ‰ ˆ S(   Nc              sS   ˆ j  ˆ ˆ ƒ j ˆ _ y ˆ  ˆ ˆ Ž  Wn# ˆ j rH ˆ j ˆ ƒ n  ‚  n Xd  S(   N(   R_   RO   RN   R*   (    (   R-   R\   R$   R   R#   R^   t   fake(    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyRa   Ù   s    	(   R_   (   R   R\   R-   R#   R$   (    (   Ra   R-   R\   R   R#   R^   R$   s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyR>   ×   s    !c         O   s'   |  j  | | | | | ƒ |  j ƒ  d  S(   N(   R1   R=   (   R   R2   R3   R-   R#   R$   (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyR4   ç   s    	c         C   sµ   xŸ |  j  r¡ |  j  d d |  j | k r¡ |  j  j d ƒ } | | d |  j 8} | d |  _ y | d | d | d Ž  Wq t k
 r } t j | ƒ q Xq W|  j | 7_ d S(   s†   Advance this reactor C{seconds} into the future.

        This is the preferred method for advancing time in your unit tests.
        i    i   i   i   N(   RT   RS   R<   R6   R   R!   (   R   R\   R^   R;   (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyt   advanceó   s    c         C   sO   |  j  d ƒ t |  _ x% |  j r= |  j |  j d d ƒ q W|  j  d ƒ d S(   sA   Continuously advance this reactor until reactor.stop() is called.t   runi    R"   N(   R&   RF   t   _runningRb   RT   (   R   (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyRc     s
    	c         C   s   t  |  _ d  S(   N(   R`   Rd   (   R   (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyR"     s    c         C   s-   t  ƒ  } | | f |  j | <| j | ƒ d S(   s}   
        Connect the given protocol with a fake transport, and keep the
        transport in C{self.udp_transports}.
        N(   R    RU   t   makeConnection(   R   t   portt   protocolt	   transport(    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyt
   listen_udp  s    	c         C   sf   y t  j | ƒ WnD t  j k
 rW | |  j k rD t |  j | ƒ St t | ƒ ƒ Sn Xt | ƒ Sd S(   si   Look up the hostname in C{self.hosts}.

        @return: A Deferred resulting in the IP address.
        N(   RG   t	   inet_atonR9   RV   R   R   R   (   R   t   hostname(    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyt   resolve  s    (   R   R   R   R   RY   R_   R*   R>   R4   Rb   Rc   R"   Ri   Rl   (    (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyRQ   ²   s   											t   TwistedReactorc           B   sz   e  Z d  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z	 d „  Z
 d	 „  Z d
 „  Z d „  Z d „  Z RS(   s7   Wrap and add functionalities to the Twisted C{reactor}.c         C   sS   d d l  m } d d l m } | |  _ | |  _ |  j ƒ  t t |  ƒ j	 ƒ  d  S(   Niÿÿÿÿ(   RR   (   t   LoopingCall(
   RW   RR   t   twisted.internet.taskRn   t   _LoopingCallRD   t   _cleanupR   Rm   R   (   R   RR   Rn   (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyR   1  s    		
c         C   s7   x0 |  j  j ƒ  D] } | j ƒ  r | j ƒ  q q Wd  S(   N(   RD   t   getDelayedCallsRN   t   cancel(   R   R^   (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyRq   :  s    c         O   s   |  j  j | | Ž  S(   s°   Call a function later.

        Simply call C{callLater(*args, **kwargs)} and return its result.

        @see: L{twisted.internet.interfaces.IReactorTime.callLater}.

        (   RD   t	   callLater(   R   R#   R$   (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyR_   A  s    c         O   s,   |  j  | | | Ž } | j | d t ƒ| S(   s±   Call a function repeatedly.

        Create a new L{twisted.internet.task.LoopingCall} object and
        start it.

        @return: the created C{LoopingCall} object.
        t   now(   Rp   t   startR`   (   R   R\   R-   R#   R$   t   lc(    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyR>   K  s    c         C   s   |  j  j | ƒ d S(   sA   Schedule a function to be called when the reactor starts running.N(   RD   t   callWhenRunning(   R   R-   (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyt   call_when_runningW  s    c         C   sX   t  | t ƒ r t j |  | ƒ St  | |  j ƒ r; | j ƒ  S| j ƒ  rT | j ƒ  n  d S(   s  Cancel a scheduled function or event handler.

        @param id: The function call or handler to remove. It can be an
            L{EventID}, a L{LoopingCall} or a C{IDelayedCall}, as returned
            by L{call_on}, L{call_every} and L{call_later} respectively.
        N(   t
   isinstanceR
   R   R*   Rp   R"   RN   Rs   (   R   R)   (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyR*   [  s    
c         O   s   |  j  j | | | Ž d S(   s1  Cause a function to be executed by the reactor thread.

        @param f: The callable object to execute.
        @param args: The arguments to call it with.
        @param kwargs: The keyword arguments to call it with.

        @see: L{twisted.internet.interfaces.IReactorThreads.callFromThread}
        N(   RD   t   callFromThread(   R   R-   R#   R$   (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyR.   i  s    	c         C   s+   |  j  d ƒ |  j j ƒ  |  j  d ƒ d S(   s2   Start the reactor, a C{"run"} event will be fired.Rc   R"   N(   R&   RD   Rc   (   R   (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyRc   t  s    c         C   s   |  j  j ƒ  |  j ƒ  d S(   s2   Stop the reactor, a C{"stop"} event will be fired.N(   RD   R"   Rq   (   R   (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyR"   {  s    c         C   s
   t  j  ƒ  S(   s5   Get current time.

        @see L{time.time}
        (   RY   (   R   (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyRY     s    c         C   s   |  j  j | | ƒ S(   s}   Connect the given protocol with a UDP transport.

        @see L{twisted.internet.interfaces.IReactorUDP.listenUDP}.
        (   RD   t	   listenUDP(   R   Rf   Rg   (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyRi   ˆ  s    c         C   s   |  j  j | ƒ S(   s©   Look up the IP of the given host.

        @return: A L{Deferred} resulting in the hostname.

        @see L{twisted.internet.interfaces.IReactorCore.resolve}.

        (   RD   Rl   (   R   t   host(    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyRl     s    (   R   R   R   R   Rq   R_   R>   Ry   R*   R.   Rc   R"   RY   Ri   Rl   (    (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyRm   -  s   				
								(   R/   RY   R7   R   RZ   RG   t   twisted.test.proto_helpersR    t   twisted.internet.deferR   R   t   twisted.internet.errorR   t   landscape.logR   R6   R   R	   t   objectR
   R   R+   RB   RJ   RM   RQ   Rm   (    (    (    s5   /usr/lib/python2.7/dist-packages/landscape/reactor.pyt   <module>   s*   C7z