
\c           @` s  d  d l  m Z m Z m Z d  d l m Z d  d l Z d  d l m Z 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 Z d  d l m Z d  d l m Z m Z d  d l m Z d d	 l m Z m Z m Z d d
 l m Z m Z m Z m 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) d d l* m+ Z+ m, Z, m- Z- m. Z. m/ Z/ d d l0 m1 Z1 m2 Z2 m3 Z3 m4 Z4 e j5 e6  Z7 d e# f d     YZ8 d e9 f d     YZ: d S(   i    (   t   print_functiont   divisiont   absolute_import(   t	   timedeltaN(   t   Empty(   t   gen(   t   IOLoopt   TimeoutError(   t   Eventi   (   t   get_address_hostt   get_local_address_fort   unparse_host_port(   t   rpct	   RPCClosedt   CommClosedErrort   coerce_to_address(   t   time(   t
   ServerNode(   t   AsyncProcess(   t   enable_proctitle_on_children(   t   Security(   t   get_ipt
   mp_contextt   silence_loggingt   json_load_robustt   PeriodicCallback(   t   _ncorest   runt   parse_memory_limitt   Workert   Nannyc           B` sv  e  Z d  Z d Z d Z d d d d d d d d d d e e e d d d d g  d d d d d d  Z d   Z	 e
 j d d   Z e d    Z e d	    Z e
 j d d
   Z d   Z d d  Z e
 j d d d   Z e
 j d d   Z e
 j d d e d   Z d   Z d   Z d   Z e
 j d    Z e d    Z d   Z e
 j d d d d   Z RS(   s    A process to manage worker processes

    The nanny spins up Worker processes, watches then, and kills or restarts
    them as necessary.
    i    s   dask-worker-spacet   autoc         K` s  | r" t  |  } | d |  _ ni | d  k rX t j j d  rX t j j d  |  _ n3 | d  k rv t |  |  _ n t | | f  |  _ | |  _ | p t |  _	 | |  _
 | |  _ | |  _ | |  _ | |  _ | |  _ | d  k r t n | |  _ | p i  |  _ | |  _ | |  _ t j j d  |  _ | p6t   |  _ t |  j t  sTt  |  j j d  |  _ |  j j d  |  _ | |  _ | pt j   |  _  t! |  j d |  j |  _" | |  _# |	 |  _$ | |  _% t& |  _' t( |
 |  j	  |  _) | rt* d |  n  | |  _+ i |  j, d 6|  j- d 6|  j. d	 6|  j/ d
 6|  j0 d 6} t1 t2 |   j3 | d |  j  d |  j |  j) rt4 |  j5 d d |  j  } | |  j6 d <n  | |  _7 d |  _8 d  S(   Nt   addresss   scheduler-addresss#   distributed.worker.memory.terminatet   workert   connection_argst   levelt   instantiatet   killt   restartt	   terminateR   t   io_loopid   t   memoryt   init(9   R   t   scheduler_addrt   Nonet   daskt   configt   getR   t   _given_worker_portR   t   ncorest	   reconnectt   validatet	   resourcest   death_timeoutt   preloadt   preload_argvR   t   envt   worker_kwargst   contact_addresst   memory_terminate_fractionR   t   securityt
   isinstancet   AssertionErrort   get_connection_argsR"   t   get_listen_argst   listen_argst	   local_dirR   t   currentt   loopR   t	   schedulert   servicest   namet   quiett   Truet   auto_restartR   t   memory_limitR   t   silence_logsR$   R%   R&   t   closeR   t   superR   t   __init__R   t   memory_monitort   periodic_callbackst   _listen_addresst   status(   t   selft   scheduler_ipt   scheduler_portt   scheduler_filet   worker_portR1   RD   RB   RF   RG   RK   R2   R3   RH   R4   RL   R5   R6   R7   R<   R:   t   listen_addresst   worker_classR8   R9   t   cfgt   handlerst   pc(    (    s0   lib/python2.7/site-packages/distributed/nanny.pyRO   /   sd    																



		c         C` s   d |  j  |  j f S(   Ns   <Nanny: %s, threads: %d>(   t   worker_addressR1   (   RT   (    (    s0   lib/python2.7/site-packages/distributed/nanny.pyt   __repr__   s    i
   c         c` s   |  j  d  k r d  S|  j  j } | d  k r/ d  St j t t t f } y6 t j t	 d |  |  j
 j d |  j  d | VWn | k
 r n Xd  S(   Nt   secondsR    t   quiet_exceptions(   t   processR,   R^   R   R   R   t   EnvironmentErrorR   t   with_timeoutR   RE   t
   unregister(   RT   t   timeoutR^   t   allowed_errors(    (    s0   lib/python2.7/site-packages/distributed/nanny.pyt   _unregister   s     	c         C` s   |  j  d  k r d  S|  j  j S(   N(   Rb   R,   R^   (   RT   (    (    s0   lib/python2.7/site-packages/distributed/nanny.pyR^      s    c         C` s   |  j  d  k r d  S|  j  j S(   N(   Rb   R,   t
   worker_dir(   RT   (    (    s0   lib/python2.7/site-packages/distributed/nanny.pyRi      s    c         c` s   | s= |  j  t |  j j  d |  j t |  j  |  _ nt t | t  r t	 t |  j j   |  _ |  j  |  j | f d |  j n( |  j  | d |  j t |  j  |  _ t
 j d |  j  |  j   V} | d k r |  j s t  d |  _ n |  j   V|  j   t j |    d S(   s2    Start nanny, start local process, start watching RA   s           Start Nanny at: %rt   runningN(   t   listenR
   RE   R    RA   R	   t   ipR=   t   intR   t   loggert   infoR$   R^   R>   RS   RM   t   start_periodic_callbacksR   t   Return(   RT   t   addr_or_portt   response(    (    s0   lib/python2.7/site-packages/distributed/nanny.pyt   _start   s$    
"
c         C` s   |  j    j   S(   N(   Rt   t	   __await__(   RT   (    (    s0   lib/python2.7/site-packages/distributed/nanny.pyRu      s    c         C` s   |  j  j |  j |  d  S(   N(   RD   t   add_callbackRt   (   RT   Rr   (    (    s0   lib/python2.7/site-packages/distributed/nanny.pyt   start   s    i   c         c` s   t  |  _ |  j d k r* t j d   n  |  j j   | } |  j j d d | |  j j    V|  j	 | |  j j    Vd S(   s    Kill the local worker process

        Blocks until both the process is down and the scheduler is properly
        informed
        t   OKRf   g?N(
   t   FalseRJ   Rb   R,   R   Rq   RD   R   R%   Rh   (   RT   t   commRf   t   deadline(    (    s0   lib/python2.7/site-packages/distributed/nanny.pyR%      s    	%c      !   c` s  |  j  r |  j  } n, |  j j d } |  j j t | |  j  } |  j d k rKt d |  j	 d |  j
 d |  j d |  j d i |  j d 6d |  j d	 |  j d
 |  j d |  j d |  j d |  j d |  j d |  j d |  j d |  j d |  j  } | j |  j  t d t   d | d | f d |  j d |  j d |  j d |  j  |  _ n  t  |  _! |  j ry, t" j# t$ d |  j  |  j j%    V} Wqt" j& k
 r|  j' d |  j  Vt" j( d   qXn |  j j%   V} t" j( |   d S(   su    Start a local worker process

        Blocks until the process is up and the scheduler is properly informed
        i    RU   R1   RB   RF   t   service_portst   nannyRG   RK   R2   R4   R3   RL   R5   R6   R7   R<   R:   t   worker_argsR9   t   worker_start_argst   on_exitR!   R8   R`   Rf   s	   timed outN()   RR   t   listenert   bound_addresst   prefixR   R0   Rb   R,   t   dictR+   R1   RB   RF   t   portRG   RK   R2   R4   R3   RL   R5   R6   R7   R<   R:   t   updateR9   t   WorkerProcesst   tuplet   _on_exitR   R8   RI   RJ   R   Rd   R   Rw   R   RM   Rq   (   RT   Rz   t	   start_argt   hostR9   t   result(    (    s0   lib/python2.7/site-packages/distributed/nanny.pyR$      sT    																						&c         #` s   t    } t j   f d    } y! t j t d |  |    VWn0 t j k
 rt t j d  t j d   n Xt j d   d  S(   Nc           3` s,     j  d  k	 r(   j   V  j   Vn  d  S(   N(   Rb   R,   R%   R$   (    (   RT   (    s0   lib/python2.7/site-packages/distributed/nanny.pyt   _!  s    R`   s,   Restart timed out, returning before finisheds	   timed outRx   (	   R   R   t	   coroutineRd   R   R   Rn   t   errorRq   (   RT   Rz   Rf   t   executor_waitRw   R   (    (   RT   s0   lib/python2.7/site-packages/distributed/nanny.pyR&     s    	!c         C` s   |  j  d k r d S|  j j } | d k r/ d Sy t j | j  } Wn t j k
 r\ d SX| j   j } | |  j	 } |  j
 r | |  j
 k r t j d d |  j
  | j   n  d S(   sE    Track worker's memory.  Restart if it goes above terminate fraction Rj   Ns.   Worker exceeded %d%% memory budget. Restartingid   (   RS   Rb   R,   t   psutilt   Processt   pidt   NoSuchProcesst   memory_infot   rssRK   R;   Rn   t   warningR'   (   RT   Rb   t   procR)   t   frac(    (    s0   lib/python2.7/site-packages/distributed/nanny.pyRP   /  s     c         C` s   |  j  d  k	 o |  j  j d k S(   NRj   (   Rb   R,   RS   (   RT   (    (    s0   lib/python2.7/site-packages/distributed/nanny.pyt   is_aliveC  s    c         O` s   t  |  | |  S(   N(   R   (   RT   t   argst   kwargs(    (    s0   lib/python2.7/site-packages/distributed/nanny.pyR   F  s    c         c` s   |  j  d k r y |  j j d |  j  VWn/ t t f k
 r[ |  j s\ |  j   Vd  Sn Xy: |  j  d k r |  j r t	 j
 d  |  j   Vq n  Wq t k
 r t	 j d d t q Xn  d  S(	   Nt   closingt   closedR    s   Restarting workers1   Failed to restart worker after its process exitedt   exc_info(   R   R   (   R   R   (   RS   RE   Re   R^   Rc   R   R2   RM   RJ   Rn   R   R$   t	   ExceptionR   RI   (   RT   t   exitcode(    (    s0   lib/python2.7/site-packages/distributed/nanny.pyR   I  s    		c         C` s   |  j  o |  j  j S(   N(   Rb   R   (   RT   (    (    s0   lib/python2.7/site-packages/distributed/nanny.pyR   ]  s    c         O` s#   t  j d d d |  j | |   S(   Ns'   Worker._close has moved to Worker.closet
   stackleveli   (   t   warningst   warnRM   (   RT   R   R   (    (    s0   lib/python2.7/site-packages/distributed/nanny.pyt   _closea  s    i   c         c` s   |  j  d k r! t j d   n  d |  _  t j d |  j  |  j   y' |  j d k	 rm |  j	 d |  Vn  Wn t
 k
 r n Xd |  _ |  j j   |  j j   d |  _  t j d   d S(   s;   
        Close the worker process, stop all comms.
        R   R   Rx   s   Closing Nanny at %rRf   N(   R   R   (   RS   R   Rq   Rn   Ro   R    t   stopRb   R,   R%   R   R   RM   RE   t	   close_rpc(   RT   Rz   Rf   t   report(    (    s0   lib/python2.7/site-packages/distributed/nanny.pyRM   e  s    	
		N(    (   t   __name__t
   __module__t   __doc__R,   Rb   RS   RI   Ry   RO   R_   R   R   Rh   t   propertyR^   Ri   Rt   Ru   Rw   R%   R$   R&   RP   R   R   R   R   R   RM   (    (    (    s0   lib/python2.7/site-packages/distributed/nanny.pyR   %   sb   F		8				R   c           B` s   e  Z d    Z e j d    Z d   Z d   Z d   Z e	 d    Z
 d   Z e j d e d   Z e j d	    Z e d
    Z RS(   c         C` sg   d |  _  | |  _ | |  _ | |  _ | |  _ | |  _ d  |  _ | |  _ | |  _	 d  |  _
 d  |  _ d  S(   NR*   (   RS   RL   R~   R9   R   R   R,   Rb   R   R8   Ri   R^   (   RT   R~   R9   R   RL   R   R!   R8   (    (    s0   lib/python2.7/site-packages/distributed/nanny.pyRO   |  s    
										c         c` s  t    |  j d k r+ t j |  j   n  |  j d k r] |  j j   Vt j |  j   n  t j   |  _ } t j   |  _	 t
 j   j } t d |  j d t d |  j d |  j d |  j d |  j d	 |  j d
 |  j	 d | d |  j d |  j  	 |  _ t |  j _ |  j j |  j  t   |  _ t   |  _ d |  _ |  j j   V|  j |  V} | sst j |  j   n  | d |  _ | d |  _  |  j st!  d |  _ |  j j"   | j#   t j |  j   d S(   s7   
        Ensure the worker process is started.
        Rj   t   startingt   targetR   R~   R9   R   RL   t   init_result_qt   child_stop_qt   uidR   R8   R    t   dirN($   R   RS   R   Rq   Rj   t   waitR   t   QueueR   R   t   uuidt   uuid4t   hexR   t   _runR   R~   R9   R   RL   R   R8   Rb   RI   t   daemont   set_exit_callbackR   R   t   stoppedRw   t   _wait_until_connectedR^   Ri   R>   t   setRM   (   RT   t   init_qR   t   msg(    (    s0   lib/python2.7/site-packages/distributed/nanny.pyRw     sJ    										
c         C` s!   | |  j  k	 r d  S|  j   d  S(   N(   Rb   t   mark_stopped(   RT   R   (    (    s0   lib/python2.7/site-packages/distributed/nanny.pyR     s    c         C` sV   | d  k	 s t  | d k r) d | f S| d k rC d | | f Sd | | f Sd  S(   Ni   s.   Worker process %d was killed by unknown signali    s'   Worker process %d exited with status %ds)   Worker process %d was killed by signal %d(   R,   R>   (   RT   R   R   (    (    s0   lib/python2.7/site-packages/distributed/nanny.pyt   _death_message  s    c         C` s   |  j  d  k	 o |  j  j   S(   N(   Rb   R,   R   (   RT   (    (    s0   lib/python2.7/site-packages/distributed/nanny.pyR     s    c         C` s&   |  j  r" |  j  j   r" |  j  j Sd  S(   N(   Rb   R   R   R,   (   RT   (    (    s0   lib/python2.7/site-packages/distributed/nanny.pyR     s    c         C` s  |  j  d k r|  j j } | d  k	 s- t  | d k ra |  j |  j j |  } t j |  n  d |  _  |  j	 j
   |  j j   d  |  _ d  |  _ d  |  _ |  j r t j j |  j  r t j |  j d t n  d  |  _ |  j d  k	 r|  j |  qn  d  S(   NR   i    t   ignore_errors(   RS   Rb   R   R,   R>   R   R   Rn   R   R   R   RM   R   R   Ri   t   ost   patht   existst   shutilt   rmtreeRI   R   (   RT   t   rR   (    (    s0   lib/python2.7/site-packages/distributed/nanny.pyR     s"    					i   c         c` sK  t  j   } | j   | } |  j d k r/ d S|  j d k rP |  j j   Vd S|  j d k se t  d |  _ |  j } |  j j	 i d d 6t
 d | | j    d	 d
 6| d 6 |  j j   x0 | j   r | j   | k  r t j d  Vq W| j   rGt j d |  y | j   VWqGt k
 rC} t j d |  qGXn  d S(   s   
        Ensure the worker process is stopped, waiting at most
        *timeout* seconds before terminating it abruptly.
        R   Nt   stoppingR   Rj   R   t   opi    g?Rf   R   g?s4   Worker process still alive after %d seconds, killings!   Failed to kill worker process: %s(   R   Rj   (   R   RC   R   RS   R   R   R>   Rb   R   t   putt   maxRM   R   R   t   sleepRn   R   R'   R   R   (   RT   Rf   R   RD   R{   Rb   t   e(    (    s0   lib/python2.7/site-packages/distributed/nanny.pyR%     s2    			!
c         c` s   d } x t  r |  j d k r" d  Sy |  j j   } Wn" t k
 rY t j |  Vq	 n X| d | k rp q	 n  d | k r t j d | d  |  j	 j
   V|  q	 t j |   q	 Wd  S(   Ng?R   R   t	   exceptions/   Failed while trying to start worker process: %s(   RI   RS   R   t
   get_nowaitR   R   R   Rn   R   Rb   t   joinRq   (   RT   R   t   delayR   (    (    s0   lib/python2.7/site-packages/distributed/nanny.pyR     s"    		c
         ` s<  t  j j |  y d d l m }
 Wn t k
 r7 n X|
   | rU t j |  n  t j	   t     j
   |	 | |    t j d t   f d        f d   } t j d | d d  } t | _ | j   t j     f d	    } y  j |  Wn! t k
 r'n t k
 r7n Xd  S(
   Ni    (   t   initialize_worker_processi   c      	   3` s9   z'  j  d t d t d | d |   VWd    j   Xd  S(   NR   R}   R   Rf   (   RM   Ry   R   (   Rf   R   (   RD   R!   (    s0   lib/python2.7/site-packages/distributed/nanny.pyt   do_stopM  s    	c          ` sq   xj t  rl y   j d d  }  Wn t k
 r2 q X  j   |  j d  d k sX t   j  |   Pq Wd S(   si   
            Wait for an incoming stop message and then stop the
            worker cleanly.
            Rf   i  R   R   N(   RI   R/   R   RM   t   popR>   Rv   (   R   (   R   R   RD   (    s0   lib/python2.7/site-packages/distributed/nanny.pyt   watch_stop_qY  s    	
R   RG   s   Nanny stop queue watchc          3` s   y  j     VWnE t k
 rY }  t j d    j i  d 6|  d 6   j   nZ X j si t    j i  j d 6 j d 6 d 6   j    j	   Vt j
 d  d S(   sK   
            Try to start worker and inform parent of outcome.
            s   Failed to start workerR   R   R    R   s   Worker closedN(   Rt   R   Rn   R   R   RM   R    R>   RB   t   wait_until_closedRo   (   R   (   R   R   R!   R   (    s0   lib/python2.7/site-packages/distributed/nanny.pyR   m  s    "
(   R   t   environR   t   dask.multiprocessingR   t   ImportErrorRn   t   setLevelR   t   clear_instancet   make_currentR   R   RI   t	   threadingt   ThreadR   Rw   t   run_syncR   t   KeyboardInterrupt(   t   clsR~   R9   R   RL   R   R   R   R8   R   R   R   t   tR   (    (   R   R   R   RD   R   R!   R   s0   lib/python2.7/site-packages/distributed/nanny.pyR   0  s2    
	
	
!(   R   R   RO   R   R   Rw   R   R   R   R   R   R   RI   R%   R   t   classmethodR   (    (    (    s0   lib/python2.7/site-packages/distributed/nanny.pyR   {  s   	1					&(;   t
   __future__R    R   R   t   datetimeR   t   loggingt   multiprocessing.queuesR   R   R   R   R   R   R   R-   t   tornadoR   t   tornado.ioloopR   R   t   tornado.locksR   Rz   R	   R
   R   t   coreR   R   R   R   t   metricsR   t   nodeR   Rb   R   t	   proctitleR   R<   R   t   utilsR   R   R   R   R   R!   R   R   R   R   t	   getLoggerR   Rn   R   t   objectR   (    (    (    s0   lib/python2.7/site-packages/distributed/nanny.pyt   <module>   s4   "(" W