a
    ‘·Df¢‚  ã                   @   sV  d 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ZeZ	z$ddl
ZddlmZ ddlmZ W n* ey–   ddlZdd„ Zdd„ ZY n0 d	d
lmZ d	dlmZ d	dlmZ ejZej ZZdZdZddlZdZG dd„ deƒZG dd„ deƒZ G dd„ dej!ƒZ"G dd„ deƒZ#G dd„ deƒZ$G dd„ deƒZ%G dd„ de&ƒZ'dS )z,
ppft: the parallel python execution server
é    N)Ú
importable)Úgetnamec                 C   s(   t  | ¡d }|d  ¡ |d< d |¡S )Nr   Ú )ÚinspectÚgetsourcelinesÚlstripÚjoin)ÚfuncÚsourcelines© r   úU/nfs/NAS7/SABIOD/METHODE/ermites/ermites_venv/lib/python3.9/site-packages/ppft/_pp.pyr   /   s    r   c                 C   s   | j S )N)Ú__name__)Úobjr   r   r   r   5   s    r   é   )Ú	transport)Úauto)Úcommoné   FTc                   @   s<   e Zd ZdZddd„Zdd„ Zdd
d„Zdd„ Zdd„ ZdS )Ú_Taskz'Class describing single task (job)
    Nr   Údefaultc                 C   sB   t  ¡ | _| j ¡  || _|| _|| _|| _|| _d| _	d| _
dS )zInitializes the taskFN)Ú	threadingÚLockÚlockÚacquireÚtidÚserverÚcallbackÚcallbackargsÚgroupÚfinishedÚ	unpickled)Úselfr   r   r   r   r   r   r   r   Ú__init__M   s    

z_Task.__init__c                 C   s(   || _ | jr|  ¡  | j ¡  d| _dS )z5Finalizes the task.

           For internal use onlyTN)Úsresultr   Ú_Task__unpickler   Úreleaser   )r!   r#   r   r   r   ÚfinalizeZ   s
    
z_Task.finalizeFc                 C   sD   | j s| jjrtdƒ‚|  ¡  | js0|s0|  ¡  |r:| jS | jS dS )zRetrieves result of the taskz.Server was destroyed before the job completionN)	r   r   Ú_exitingÚDestroyedServerErrorÚwaitr    r$   r#   Úresult)r!   Z
raw_resultr   r   r   Ú__call__d   s    
z_Task.__call__c                 C   s   | j s| j ¡  | j ¡  dS )zWaits for the taskN)r   r   r   r%   ©r!   r   r   r   r)   r   s    
z
_Task.waitc                 C   sX   t  t | j¡¡\| _}d| _t|ƒdkr6t|dd | j	rT| j
| jf }| j	|Ž  dS )z Unpickles the result of the taskTr   ú )ÚendN)ÚpickleÚloadsÚppcZb_r#   r*   r    ÚlenÚprintr   r   )r!   ZsoutÚargsr   r   r   Z
__unpicklex   s    z_Task.__unpickle)Nr   r   )F)	r   Ú
__module__Ú__qualname__Ú__doc__r"   r&   r+   r)   r$   r   r   r   r   r   I   s     ÿ


r   c                   @   sP   e Zd ZdZejdddgZe d¡ dd„ Zdd	„ Z	d
d„ Z
dd„ Zdd„ ZdS )Ú_WorkerzLocal worker class
    z-uz-mZppftz2>/dev/nullc                 C   s   || _ || _|  ¡  dS )zInitializes local workerN)Úrestart_on_freeÚpickle_protoÚstart)r!   r9   r:   r   r   r   r"   Š   s    z_Worker.__init__c                 C   sX   t j| jt jt jt jd}t |j|j¡| _t	| j 
¡ ƒ| _| j t| jƒ¡ d| _dS )zStarts local worker)ÚstdinÚstdoutÚstderrTN)Ú
subprocessÚPopenÚcommandÚPIPEÚpptransportZCPipeTransportr=   r<   ÚtÚintÚreceiveÚpidÚsendÚstrr:   Úis_free)r!   Úprocr   r   r   r;      s    ÿz_Worker.startc                 C   s    d| _ | j d¡ | j ¡  dS )zStops local workerFZEXITN)rJ   rD   rH   Úcloser,   r   r   r   ÚstopŸ   s    z_Worker.stopc                 C   s   |   ¡  |  ¡  dS )zRestarts local workerN)rM   r;   r,   r   r   r   Úrestart¦   s    z_Worker.restartc                 C   s   | j r|  ¡  nd| _dS )zFrees local workerTN)r9   rN   rJ   r,   r   r   r   Úfree«   s    
z_Worker.freeN)r   r5   r6   r7   ÚsysÚ
executablerA   Úappendr"   r;   rM   rN   rO   r   r   r   r   r8   ƒ   s   
r8   c                   @   s*   e Zd ZdZdd„ Zdd„ Zd	dd„ZdS )
Ú_RWorkerzRemote worker class
    c                 C   sf   || _ || _|| _|| _|| _||f| _|d t|ƒ | _| j j 	d| j|f ¡ || _
|  |¡ dS )zInitializes remote workerú:z$Creating Rworker id=%s persistent=%sN)r   Ú
persistentÚhostÚportÚsecretÚaddressrI   ÚidÚloggerÚdebugÚsocket_timeoutÚconnect)r!   rV   rW   rX   r   ÚmessagerU   r]   r   r   r   r"   ·   s    

ÿz_RWorker.__init__c                 C   s   |   ¡  dS )z$Closes connection with remote serverN)rL   r,   r   r   r   Ú__del__Å   s    z_RWorker.__del__Nc              	   C   sâ   | j jsÞzhtj | d| j¡ |  | j| j¡ |  	| j
¡sX| j j d| j| jf ¡ W dS |rf|  |¡ d| _W dS    trŽ| j jjddd | js°| j j d| jf ¡ Y dS | j j d| j| jtf ¡ t t¡ Y q 0 q dS )	zConnects to a remote serverTNz*Authentication failed for host=%s, port=%sFz/Exception in connect method (possibly expected)©Úexc_infozDeleting from queue Rworker %szCFailed to reconnect with (host=%s, port=%i), will try again in %i s)r   r'   rC   ZSocketTransportr"   r]   Ú_connectrV   rW   ZauthenticaterX   r[   ÚerrorrH   rJ   ÚSHOW_EXPECTED_EXCEPTIONSr\   rU   rZ   ÚinfoÚRECONNECT_WAIT_TIMEÚtimeÚsleep)r!   r_   r   r   r   r^   É   s6    

ÿ

ÿ
ÿ
þz_RWorker.connect)N)r   r5   r6   r7   r"   r`   r^   r   r   r   r   rS   ³   s   rS   c                   @   s   e Zd ZdZddd„ZdS )Ú_Statisticsz9Class to hold execution statisitcs for a single node
    Nc                 C   s   || _ d| _d| _|| _dS )z!Initializes statistics for a nodeç        r   N)Úncpusrh   ÚnjobsÚrworker)r!   rl   rn   r   r   r   r"   í   s    z_Statistics.__init__)N)r   r5   r6   r7   r"   r   r   r   r   rj   é   s   rj   c                   @   s"   e Zd ZdZd	dd„Zdd„ ZdS )
ÚTemplatezTemplate class
    r   Nr   c	           	      C   s4   || _ || _|| _|| _|| _|| _|| _|| _dS )aù  Creates Template instance

           jobs_server - pp server for submitting jobs
           func - function to be executed
           depfuncs - tuple with functions which might be called from 'func'
           modules - tuple with module names to import
           callback - function which will be called with argument list equal                    to callbackargs+(result,) as soon as calculation is done
           callbackargs - additional arguments for callback function
           group - job group, is used when wait(group) is called to wait for                    jobs in a given group to finish
           globals - dictionary from which all modules, functions and classes                    will be imported, for instance: globals=globals()
        N)Ú
job_serverr	   ÚdepfuncsÚmodulesr   r   r   Úglobals)	r!   rp   r	   rq   rr   r   r   r   rs   r   r   r   r"   ù   s    zTemplate.__init__c              
   G   s(   | j  | j|| j| j| j| j| j| j¡S )zDSubmits function with *arg arguments to the execution queue
        )	rp   Úsubmitr	   rq   rr   r   r   r   rs   )r!   r4   r   r   r   rt     s    þzTemplate.submit)r   r   Nr   r   N)r   r5   r6   r7   r"   rt   r   r   r   r   ro   õ   s
     ÿ
ro   c                   @   sì   e Zd ZdZdZdZd>d
d„Zd?dd„Zd@dd„Zdd„ Z	dAdd„Z
dd„ Zdd„ Zdd„ ZdBdd„ZdCdd„Zd d!„ Zd"d#„ Zd$d%„ Zd&d'„ Zd(d)„ Zd*d+„ Zd,d-„ Zd.d/„ Zd0d1„ Zd2d3„ Zd4d5„ Zd6d7„ Zd8d9„ Zd:d;„ Zd<d=„ ZdS )DÚServerz/Parallel Python SMP execution server class
    i`ê  zepo20pdosl;dksldkmmÚ
autodetectr   NFé   é  c                    sª  t |tƒstdƒ‚t d¡| _| j dt d ¡ | j dtj 	d¡d tj
¡ d| _d| _t ¡ | _g | _t ¡ | _g | _g | _g | _i | _i | _g | _t ¡ | _d| _d	| _i | _t ¡ | _|| _|| _i | _t  !¡ gtj" }d
t j#v rt j#d
 rt j#d
  	t j$¡| }t%ƒ ‰ t j$ &‡ fdd„|D ƒ¡t j#d
< t' (| j)¡ dt*dƒi| _+|  ,|¡ g | _-g | _.|| _/|D ]œ}| 	d¡}|d }	t0|ƒdkr¢t1|d ƒ}
nt2 3¡ }
|	 4d¡dkrÌ| j- 5|	|
f¡ n>|	dkrÚd}	|	 6dd¡}|	 6dd¡}| j. 5||
f||
ff¡ qpt ¡ | _7|durBt |t8ƒs6tdƒ‚t8|ƒ| _9n>t:t;dƒrxt<t;dƒ}t |t8ƒsltdƒ‚t8|ƒ| _9nt=j>| _9|  ?¡  t@ @¡ | _A| j d| jBf ¡ dS )a£  Creates Server instance

           ncpus - the number of worker processes to start on the local                    computer, if parameter is omitted it will be set to                    the number of processors in the system
           ppservers - list of active parallel python execution servers                    to connect with
           secret - passphrase for network connections, if omitted a default                    passphrase will be used. It's highly recommended to use a                    custom passphrase for all network connections.
           restart - restart the worker process after each task completion
           proto - protocol number for pickle module
           socket_timeout - socket timeout in seconds, which is the maximum                    time a remote job could be executed. Increase this value                    if you have long running jobs or decrease if connectivity                    to remote ppservers is often lost.

           With ncpus = 1 all tasks are executed consequently.
           For the best performance either use the default "autodetect" value
           or set ncpus to the total number of processors in the system.
        z"ppservers argument must be a tupleÚppzCreating server instance (pp-ú)zRunning on Python %s %sr-   r   FTÚ
PYTHONPATHc                    s"   g | ]}|ˆ vrˆ   |¡p|‘qS r   )Úadd©Ú.0Úx©Zdirsetr   r   Ú
<listcomp>Z  ó    z#Server.__init__.<locals>.<listcomp>ÚlocalrT   r   Ú*éÿÿÿÿz*.*.*.*Ú0Z255Nzsecret must be of a string typeZ	pp_secretz'pp local server started with %d workers)CÚ
isinstanceÚtupleÚ	TypeErrorÚloggingÚ	getLoggerr[   rf   ÚversionrP   ÚsplitÚplatformÚ_Server__tidÚ_Server__active_tasksr   r   Ú_Server__active_tasks_lockÚ_Server__queueÚ_Server__queue_lockÚ_Server__workersÚ_Server__rworkersÚ_Server__rworkers_reservedÚ_Server__sourcesHMÚ_Server__sfuncHMÚ_Server__waittasksÚ_Server__waittasks_lockr'   Ú_Server__accurate_statsÚautopp_listÚ"_Server__active_rworkers_list_lockÚ_Server__restart_on_freeÚ_Server__pickle_protoÚ_Server__connect_locksÚosÚgetcwdÚpathÚenvironÚpathsepÚsetr   ÚatexitÚregisterÚdestroyrj   Ú_Server__statsÚ	set_ncpusÚ	ppserversÚauto_ppserversr]   r2   rE   r1   Z
randomportÚfindrR   ÚreplaceÚ_Server__stats_lockrI   rX   ÚhasattrÚuserÚgetattrru   Údefault_secretÚ_Server__connectrh   Ú_Server__creation_timeÚ_Server__ncpus)r!   rl   r¬   rX   rN   Úprotor]   Z
pythondirsÚppserverrV   rW   Z	interfaceÚ	broadcastr   r€   r   r"   !  sˆ    
ÿ



 


ÿ




ÿzServer.__init__r   c	                 C   sN  | j rtdƒ‚t|tƒs tdƒ‚t|tƒs2tdƒ‚t|tƒsDtdƒ‚t|tƒsVtdƒ‚|durpt|tƒsptdƒ‚|D ]}	t|	tƒsttdƒ‚qt|  ¡ }
tj	}|r|t|  
d	|¡ƒ7 }tt|ƒƒ}| j d
|
t|ƒf ¡ | ¡ D ]$}t|tj	ƒsút||ƒrà||f7 }qàt| |
|||ƒ}| j ¡  | j |¡ | j ¡  t|tjƒr^|j}|dur^|f| }|D ]\}tt|ƒƒdd… dkrbtt |¡ddƒdv ršn"t ||¡rb|tt |j¡ƒ7 }qb|D ]}t|tj	ƒrÄ||f7 }qÄ|  |f| |¡}t  !|| j"¡}| j# ¡  | j$ |||f¡ | j# ¡  | j d|
t%|ƒf ¡ |  &¡  |S )a  Submits function to the execution queue

           func - function to be executed
           args - tuple with arguments of the 'func'
           depfuncs - tuple with functions which might be called from 'func'
           modules - tuple with module names to import
           callback - function which will be called with argument list equal                    to callbackargs+(result,) as soon as calculation is done
           callbackargs - additional arguments for callback function
           group - job group, is used when wait(group) is called to wait for                    jobs in a given group to finish
           globals - dictionary from which all modules, functions and classes                    will be imported, for instance: globals=globals()
        z6Cannot submit jobs: server instance has been destroyedzargs argument must be a tuplez!depfuncs argument must be a tuplez modules argument must be a tuplez%callbackargs argument must be a tupleNz%globals argument must be a dictionaryz*modules argument must be a list of stringsr   z(Task %i will autoimport next modules: %sé   z<classr   )ÚbuiltinsNzTask %i submited, function='%s')'r'   r(   r‡   rˆ   r‰   ÚdictrI   Ú_Server__gentidÚtypesÚFunctionTypeÚ_Server__find_modulesr¦   r[   r\   Úvaluesr   rš   r   r™   rR   r%   Ú
MethodTypeÚ__self__Útyper³   r   Ú	getmoduler1   Zis_not_importedZget_class_hierarchyÚ	__class__Ú_Server__dumpsfuncr/   ÚdumpsrŸ   r“   r’   r   Ú_Server__scheduler)r!   r	   r4   rq   rr   r   r   r   rs   Úmoduler   Z
other_typeZobject1ÚtaskZ	func_selfÚargÚsfuncÚsargsr   r   r   rt   …  sr    






ÿÿ



ÿ


ÿzServer.submitc                 C   sL   | j  ¡  | jD ](}|r"|j|kr| j  ¡  | ¡   q q| j  ¡  qHq dS )zsWaits for all jobs in a given group to finish.
           If group is omitted waits for all jobs to finish
        N)rš   r   r™   r   r%   r)   )r!   r   rÌ   r   r   r   r)   å  s    



zServer.waitc                 C   s   | j S )z8Returns the number of local worker processes (ppworkers))r·   r,   r   r   r   Ú	get_ncpusô  s    zServer.get_ncpusc                    s~   |dkrˆ   ¡ }t|tƒs"tdƒ‚|dk r2tdƒ‚|tˆ jƒkrhˆ j ‡ fdd„t|tˆ jƒ ƒD ƒ¡ |ˆ j	d _
|ˆ _dS )	zÈSets the number of local worker processes (ppworkers)

        ncpus - the number of worker processes, if parammeter is omitted
                it will be set to the number of processors in the systemrv   zncpus must have 'int' typer   zncpus must be an integer > 0c                    s   g | ]}t ˆ jˆ jƒ‘qS r   )r8   rž   rŸ   r}   r,   r   r   r     s   ÿÿz$Server.set_ncpus.<locals>.<listcomp>rƒ   N)Ú_Server__detect_ncpusr‡   rE   r‰   Ú
ValueErrorr2   r”   ÚextendÚrangerª   rl   r·   ©r!   rl   r   r,   r   r«   ø  s    
þzServer.set_ncpusc                 C   sB   i }| j  ¡ D ].\}}|dks2|| jv r| j| r|j||< q|S )zKReturns active nodes as a dictionary
        [keys - nodes, values - ncpus]rƒ   )rª   Úitemsrœ   rl   )r!   Zactive_nodesÚnodeÚstatr   r   r   Úget_active_nodes
  s    ÿzServer.get_active_nodesc                 C   sZ   | j  ¡ D ]H\}}|jr
z |j d¡ t|j ¡ ƒ|_W q
   d| _d|_Y q
0 q
| j S )z0Returns job execution statistics as a dictionaryZTIMEFrk   )rª   rÖ   rn   rH   ÚfloatrF   rh   r›   )r!   r×   rØ   r   r   r   Ú	get_stats  s    zServer.get_statsc                 C   sÆ   t dƒ t ¡ | j }t|  ¡  ¡ ƒ}d}|D ]\}}||j7 }q.t dƒ |D ]:\}}|jrNt d|jd|j | |j|j|j |f ƒ qNt d| ƒ t d| j|  ¡ f ƒ | j	sºt dƒ t d	ƒ d
S )zOPrints job execution statistics. Useful for benchmarking on
           clusterszJob execution statistics:rk   zE job count | % of all jobs | job time sum | time per job | job serverz1    %6i |        %6.2f |     %8.4f |  %11.6f | %sg      Y@z%Time elapsed since server creation %sz%s active tasks, %s coreszJWARNING: statistics provided above is not accurate due to job reschedulingr   N)
r3   rh   r¶   ÚlistrÛ   rÖ   rm   r   rÐ   r›   )r!   ZwalltimeÚ
statisticsZ	totaljobsr¹   rØ   r   r   r   Úprint_stats   s*    ÿÿÿzServer.print_statsc                 C   s\   |s|   ¡ }t| |ƒ}| j ¡  | j |||f¡ | j ¡  | j d|j	f ¡ |  
¡  |S )zqInserts function into the execution queue. It's intended for
           internal use only (in ppserver).
        zTask %i inserted)r¾   r   r“   r   r’   rR   r%   r[   r\   r   rÊ   )r!   rÎ   rÏ   rÌ   r   r   r   r   Úinsert<  s    


zServer.insertTc           	   	   C   s\  |d t |ƒ }| j |t ¡ ¡}| ¡  z zð|| jv rJW W | ¡  dS t||| j	| d|| j
ƒ}t| ¡ ƒ}t||ƒ| j|< t|ƒD ]6}t||| j	| d|| j
ƒ}|  |jd¡ | j |¡ q†t|ƒD ]6}t||| j	| d|| j
ƒ}|  |jd¡ | j |¡ qÆ| j d|||f ¡ |  ¡  W n"   tr<| jjddd	 Y n0 W | ¡  n
| ¡  0 dS )
z7Conects to a remote ppserver specified by host and portrT   NZSTATÚEXECr   zLConnected to ppserver (host=%s, port=%i)                     with %i workersz0Exception in connect1 method (possibly expected)Tra   )rI   r    Ú
setdefaultr   r   r   rœ   r%   rS   rX   r]   rE   rF   rj   rª   rÔ   Ú_Server__update_active_rworkersrZ   r•   rR   r–   r[   r\   rÊ   re   )	r!   rV   rW   rU   Zhostidr   rn   rl   r   r   r   r   Úconnect1K  s6    
åÿzServer.connect1c                 C   sL   | j D ]}t d| j|¡ qt | d¡| _| jD ]}t d| jj|¡ q0dS )z Connects to all remote ppserversrã   Tzdiscover.runN)	r¬   r1   Ústart_threadrã   ÚppautoZDiscoverZdiscoverr­   Úrun)r!   r¹   r   r   r   Z	__connecto  s
    

zServer.__connectc                 C   st   t tdƒrLdtjv r6t d¡}t|tƒrL|dkrL|S ntt d¡d  ¡ ƒS dtjv rpttjd ƒ}|dkrp|S dS )z2Detects the number of effective CPUs in the systemÚsysconfÚSC_NPROCESSORS_ONLNr   zsysctl -n hw.ncpur   ZNUMBER_OF_PROCESSORS)	r±   r¡   Úsysconf_namesrç   r‡   rE   Zpopen2Úreadr¤   rÕ   r   r   r   Z__detect_ncpusx  s    



zServer.__detect_ncpusc                    sT   t || ƒ}|ˆ jvrJ‡ fdd„|D ƒ}t t|d ƒ||fˆ j¡ˆ j|< ˆ j| S )z Serializes functions and modulesc                    s   g | ]}ˆ   |¡‘qS r   )Ú_Server__get_source)r~   r	   r,   r   r   r   ‘  r‚   z&Server.__dumpsfunc.<locals>.<listcomp>r   )Úhashr˜   r/   rÉ   r   rŸ   )r!   Úfuncsrr   ZhashsÚsourcesr   r,   r   Z__dumpsfunc  s    
þ
zServer.__dumpsfuncc                 C   sj   g }|  ¡ D ]X\}}t|tjƒr|dvr|j|| ks>|dkr| |j¡ | |  |jd |j¡¡ q|S )z)recursively finds all the modules in dict)Ú__builtins__ry   r   Ú.)	rÖ   r‡   r¿   Ú
ModuleTyper   rR   rÓ   rÁ   Ú__dict__)r!   Úprefixr½   rr   ÚnameÚobjectr   r   r   Z__find_modules˜  s    ÿÿzServer.__find_modulesc                 C   s|  | j  ¡  | jrn| j| jk r¢| j d¡}| jD ]}|jr0d|_ qZq0| j 	d¡ t
dƒ‚|  d¡ z.| jd  jd7  _t d| j||f ¡ W n   Y n0 q
| jD ]L}|jr¨d|_| j d¡}| j|j  jd7  _t d| j||f ¡  q
q¨t| jƒ| jkrn| jD ]R}|jrd|_| j d¡}| j|j  jd7  _t d| j||f ¡  qlqqnq
qnq
| j  ¡  d	S )
zSchedules jobs for executionr   FzThere are no free workers leftzError: No free workersr   rƒ   Z	run_localZ
run_remoteN)r“   r   r’   r   r·   Úpopr”   rJ   r[   rd   ÚRuntimeErrorÚ_Server__add_to_active_tasksrª   rm   r1   rä   Ú
_run_localr•   rZ   Ú_run_remoter2   r–   r%   )r!   rÌ   Úworkerrn   r   r   r   Z__scheduler¤  sD    





zServer.__schedulerc                 C   s*   t |ƒ}|| jvr t|ƒ| j|< | j| S )zFetches source of the function)rì   r—   r   )r!   r	   Zhashfr   r   r   Z__get_sourceÐ  s    
zServer.__get_sourcec                 C   sî   | j r
dS | j d|j¡ t ¡ }z0|j |¡ |j |¡ |j ¡ }| 	|¡ W n,   | j rfY dS t
rz| jjddd Y n0 | jr¦| j ¡  | j |¡ | j ¡  | ¡  |  d¡ | j sÒ|  dt ¡ | ¡ | j d|j¡ |  ¡  dS )	zRuns a job locallyNzTask %i startedz+Exception in _run_local (possibly expected)Tra   r…   rƒ   zTask %i ended)r'   r[   rf   r   rh   rD   ÚcsendrH   rF   r&   re   r\   r™   rš   r   Úremover%   rO   rø   Ú_Server__stat_add_timerÊ   )r!   ÚjobrÎ   rÏ   rû   Ú
start_timer#   r   r   r   rù   ×  s0    



zServer._run_localc                 C   sæ   | j  d|j¡ z0| |¡ | |¡ | ¡ }d|_| |¡ W nb   | j  d|j¡ |  |||¡ |  	¡  |  
|jd¡ | d¡rœ|  
|jd¡ |  	¡  Y dS 0 | jrÊ| j ¡  | j |¡ | j ¡  | j  d|j¡ |  	¡  dS )	zRuns a job remotellyzTask (remote) %i startedTz>Task %i failed due to broken network connection - reschedulingr…   rà   r   NzTask (remote) %i ended)r[   r\   r   rü   rH   rF   rJ   r&   rß   rÊ   râ   rZ   r^   r™   rš   r   rý   r%   )r!   rÿ   rÎ   rÏ   rn   r#   r   r   r   rú   þ  s0    

ÿ


zServer._run_remotec                 C   s&   | j  ¡  |  j|7  _| j  ¡  dS )z"Updates the number of active tasksN)r‘   r   r   r%   )r!   Únumr   r   r   Z__add_to_active_tasks"  s    
zServer.__add_to_active_tasksc                 C   s,   | j  ¡  | j|  j|7  _| j  ¡  dS )z!Updates total runtime on the nodeN)r°   r   rª   rh   r%   )r!   r×   Ztime_addr   r   r   Z__stat_add_time(  s    
zServer.__stat_add_timec                 C   s,   | j  ¡  | j|  jd7  _| j  ¡  dS )z Increments job count on the noder   N)r°   r   rª   rm   r%   )r!   r×   r   r   r   Z__stat_add_job.  s    
zServer.__stat_add_jobc                 C   s>   | j  ¡  || jvrd| j|< | j|  |7  < | j  ¡  dS )zUpdates list of active rworkersr   N)r   r   rœ   r%   )r!   rZ   Úcountr   r   r   Z__update_active_rworkers4  s
    


zServer.__update_active_rworkersc                 C   s   |  j d7  _ | j d S )z Generates a unique job ID numberr   )r   r,   r   r   r   Z__gentid>  s    zServer.__gentidc                 C   s
   d| _ d S )NT)r'   r,   r   r   r   r`   C  s    zServer.__del__c                 C   sŽ   d| _ | j ¡  g | _| j ¡  | jD ]b}zP|j ¡  tj	 
d¡r\t dt|jƒ d ¡ nt |jd¡ t |jd¡ W q&   Y q&0 q&dS )z%Kills ppworkers and closes open filesTÚwinzTASKKILL /PID z	 /F 2>NULé	   r   N)r'   r“   r   r’   r%   r”   rD   rL   rP   rŽ   Ú
startswithr¡   ÚpopenrI   rG   ÚkillÚwaitpid)r!   rû   r   r   r   r©   F  s    



zServer.destroy)rv   r   NFrw   rx   )r   r   r   Nr   r   N)N)rv   )N)T)r   r5   r6   r7   Údefault_portr´   r"   rt   r)   rÐ   r«   rÙ   rÛ   rÞ   rß   rã   rµ   rÑ   rÈ   rÁ   rÊ   rë   rù   rú   rø   rþ   Z_Server__stat_add_jobrâ   r¾   r`   r©   r   r   r   r   ru     s@     ÿ
d  ÿ
`




$	,'$
ru   c                   @   s   e Zd ZdS )r(   N)r   r5   r6   r   r   r   r   r(   Y  s   r(   )(r7   r¡   r   rŠ   r   rP   r¿   rh   r§   r²   Zdillr/   Zdill.sourcer   r   ÚImportErrorr   r   rC   r   rå   r   r1   Ú	copyrightÚ__version__rŒ   rg   re   r?   Z_USE_SUBPROCESSrõ   r   r8   ZCSocketTransportrS   rj   ro   ru   r÷   r(   r   r   r   r   Ú<module>   sJ   
:06%    C