
    wiÃ              
          d dl Z	 d dlZn# e$ r d dlZY nw xY w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mZ d dlmZmZmZmZmZmZmZmZ 	 d dlZdZn# e$ r dZY nw xY w	 d dlZdZn# e$ r dZdZY nw xY wd dlm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z& d dl'm(Z(m)Z)m*Z* d d	l+m,Z,m-Z- d d
l.m/Z/m0Z0m1Z1 d dl2m3Z3 d dl4m5Z5m6Z6 d dl7m8Z8m9Z9 d dl:m;Z;  G d d          Z<e(r@ G d de<e)d         d         j=                  Z> G d de<e)d         d         j=                  Z? G d de<e)d         d         j=                  Z@ G d de<e)d         j                  ZAerbe(r@ G d de<e)d         d         j=                  ZB G d  d!e<e)d"         d         j=                  ZC G d# d$e<e)d"         d         j=                  ZDd%eEd&eFd'eee<ej=        ef                  fd(ZGdS ))    N)partial)current_threadmain_threadThread)AnyCallableDictListOptionalTupleTypeUnionTF)
APPLY_PILL	EXIT_FUNC	INIT_FUNCNEW_MAP_PARAMS_PILLNON_LETHAL_POISON_PILLPOISON_PILLWorkerComms)FORK_AVAILABLEMP_CONTEXTSRUNNING_WINDOWS)DashboardConnectionDetailsset_dashboard_connection)CannotPickleExceptionErrorInterruptWorker
StopWorker)WorkerInsights)WorkerMapParamsWorkerPoolParams)TqdmConnectionDetailsTqdmManager)TimeItc                   "    e Zd ZdZdededededede	de
d	ed
df fdZd2dZd2dZd2dZd2dZd2dZd2dZd3deded
efdZdeded
dfdZd
ee         fdZd
eeeef         ed         f         fdZd
efdZdedee         dee         d
eeeeef         fd Zd
efd!Z 	 d4dedee         d"ee         d
eeeeef         fd#Z!dee         dee         d$ee"e#f         d
dfd%Z$dee         d$ee"e#f         d
ee%ee&e'f         fd&Z(d5dee         d(e'd
e'fd)Z)dedeeef         d
eeef         fd*Z*d4deded+ee&         d
efd,Z+d4deded+ee&         d
efd-Z,e-d4ded+ee&         d
eee&f         fd.            Z.d3d/ed
dfd0Z/d3d/ed
dfd1Z0 xZ1S )6AbstractWorkerzx
    A multiprocessing helper class which continuously asks the queue for new jobs, until a poison pill is inserted
    	worker_idpool_params
map_paramsworker_commsworker_insightstqdm_connection_detailsdashboard_connection_details
start_timereturnNc	                    t                                                       || _        || _        || _        || _        || _        || _        || _        || _	        i | _
        d| _        t          j                    | _        d| _        | j        | _        | j                            | j                  | _        d| _        d| _        d| _        dS )a  
        :param worker_id: Worker ID
        :param pool_params: WorkerPool parameters
        :param map_params: WorkerPool map parameters
        :param worker_comms: Worker communication objects (queues, locks, events, ...)
        :param worker_insights: WorkerInsights object which stores the worker insights
        :param tqdm_connection_details: Tqdm manager host, and whether the manager is started/connected
        :param dashboard_connection_details: Dashboard manager host, port_nr and whether a dashboard is
            started/connected
        :param start_time: Timestamp indicating at what time the Worker instance was created and started
        Nr   F)super__init__r&   r'   r(   r)   r*   r+   r,   r-   worker_stateadditional_argstimeprogress_bar_last_updatedprogress_bar_n_tasks_completedmax_task_duration_last_updatedget_max_task_duration_listmax_task_duration_listis_apply_funclast_job_idinit_func_completed)
selfr&   r'   r(   r)   r*   r+   r,   r-   	__class__s
            d/var/www/development/aibuddy-work/election-extract/venv/lib/python3.11/site-packages/mpire/worker.pyr1   zAbstractWorker.__init__+   s     	 #&$(.'>$,H)$   $)-&./+.2.L+&*&:&U&UVZVd&e&e#"#(       c                    |                                   d}	 | j                            | j                   | j                            | j                   t          j        | j                   t          | j	        d           | j
                            | j        | j                   |                                  |                     | j        j                  }| j        j        || j        j        k     rt%          | j
        j        | j                  5  | j                            | j                  }d}d}ddd           n# 1 swxY w Y   |t*          k    s|t,          k    r|t*          k    }|                     ||           |r	 | j                            | j                   | j                                        s;| j        j        /|| j        j        k    r| j                            | j                   | j                            | j                   dS G|t8          k    r|                                 }|	 | j                            | j                   | j                                        s;| j        j        /|| j        j        k    r| j                            | j                   | j                            | j                   dS |t<          k    r|                                 \  }}|	 | j                            | j                   | j                                        s;| j        j        /|| j        j        k    r| j                            | j                   | j                            | j                   dS d}n|	 | j                            | j                   | j                                        s;| j        j        /|| j        j        k    r| j                            | j                   | j                            | j                   dS 	 |\  }}| j        j         r| !                                r	 d| _"        | j        #                    | j                   | j                            | j                   | j                                        s;| j        j        /|| j        j        k    r| j                            | j                   | j                            | j                   dS || _"        g }|D ]}	| $                    |r|n|||	          \  }
}}}|r d| _"        | j        #                    | j                   | j                            | j                   | j                                        s;| j        j        /|| j        j        k    r| j                            | j                   | j                            | j                   dS |r|%                    |||
f           |s| &                                 |r | j        '                    | j        |           |tQ          |          z  }d| _"        | j        #                    | j                   n+# d| _"        | j        #                    | j                   w xY w| )                                 | j        j        || j        j        k     | )                    d           | &                    d           | j        j*        r| +                                r	 | j                            | j                   | j                                        s;| j        j        /|| j        j        k    r| j                            | j                   | j                            | j                   dS | j                            | j                   | j                                        s;| j        j        /|| j        j        k    r| j                            | j                   | j                            | j                   dS # | j                            | j                   | j                                        s;| j        j        /|| j        j        k    r| j                            | j                   | j                            | j                   w xY w)z
        Continuously asks the tasks queue for new task arguments. When not receiving a poisonous pill or when the max
        life span is not yet reached it will execute the new task and put the results in the results queue.
        r   F)auto_connectNTforce_update),_set_signal_handlersr)   signal_worker_aliver&   reset_results_receivedr"   set_connection_detailsr+   r   r,   r*   update_start_up_timer-   _set_additional_args	_get_funcr(   funcworker_lifespanr#   worker_waiting_timeget_taskr   r   _handle_poison_pillwait_for_all_results_receivedexception_thrownsignal_worker_restartsignal_worker_deadr   _handle_new_map_paramsr   _handle_apply_pillworker_init_run_init_funcr:   	task_done	_run_funcappend_update_progress_baradd_resultslen_update_task_insightsworker_exit_run_exit_func)r=   n_tasks_executedrL   next_chunked_args
apply_funcr:   lethaljob_idresultsargsresults_partsuccesssend_resultsshould_shut_downs                 r?   runzAbstractWorker.runS   s)	    	!!###m	A11$.AAA44T^DDD .t/KLLL$T%FUZ[[[[  55dndoVVV %%''' >>$/"677D/19=MPTP_Po=o=o D0DdnUU * *(,(9(B(B4>(R(R%!%J$)M* * * * * * * * * * * * * * * %337HLb7b7b.+=F,,V5EFFF L ;;DNKKK %6688 HT_=\=h$(GGG!77GGG00@@@@@Y  '*===6688D|~ ;;DNKKK %6688 HT_=\=h$(GGG!77GGG00@@@@@K  '*44484K4K4M4M1J 1!)p ;;DNKKK %6688 HT_=\=h$(GGG!77GGG00@@@@@} %)MM '.f ;;DNKKK %6688 HT_=\=h$(GGG!77GGG00@@@@@o#@0A-F- 2 t7J7J7L7L 8 */D&%//??? ;;DNKKK %6688 HT_=\=h$(GGG!77GGG00@@@@@] *7D& G 1 8 8 QUP^P^*7AJJT64Q QMg|=M , #" */D&%//??? ;;DNKKK %6688 HT_=\=h$(GGG!77GGG00@@@@@G ( L#NNFG\+JKKK  - 8 55777  O)55dngNNN$G4$ */D&%//???? */D&%//???? **,,,S /19=MPTP_Po=o=oX &&D&999%%4%888* t/B/B/D/D  ;;DNKKK %6688 HT_=\=h$(GGG!77GGG00@@@@@ ;;DNKKK %6688 HT_=\=h$(GGG!77GGG00@@@@@ ;;DNKKK %6688 HT_=\=h$(GGG!77GGG00@@@@su   Da $E	=a 	Ea E<a "#a &a a 0%Z &a 1Z &a ;A&Z !'a (Z00Ba Bc.c                    t                      t                      k    rdS t          st          j        t          j        t          j                   t          j        t          j        | j                   t          j        t          j        | j                   t          j        t          j	        | j
                   dS t          r~| j        j        dk    rpt                      t                      k    rTt          j        t          j        | j
                   t          | j        d          }|                                 dS dS dS dS )z;
        Set signal handlers for graceful shutdown
        N	threadingT)targetdaemon)r   r   r   signalSIGINTSIG_IGNSIGHUP_on_kill_exit_gracefullySIGTERMSIGUSR1_on_exception_exit_gracefullyr'   start_methodr   %_on_exception_exit_gracefully_windowsstart)r=   ts     r?   rE   z#AbstractWorker._set_signal_handlers   s   
 {}},,F  
	M&-888M&-)FGGGM&.$*GHHHM&.$*LMMMMM  	!1!>+!M!MR`RbRbfqfsfsRsRsM&-)KLLLdHQUVVVAGGIIIII	 	!M!MRsRsr@   c                 "   t          d| j         d          }| j                            | j                  5  | j                            | j                  r||                     | j        d|           	 ddd           dS # 1 swxY w Y   dS )a3  
        When someone manually sends a kill signal to this process, we want to exit gracefully. We do this by raising an
        exception when a task is running. Otherwise, we call raise() ourselves with the exception. Both will ensure
        exception_thrown() is set and will shutdown the pool.
        zWorker-z was killedN)RuntimeErrorr&   r)   get_worker_running_task_lockget_worker_running_task_raiser;   )r=   _errs      r?   rv   z'AbstractWorker._on_kill_exit_gracefully   s     @T^@@@AA;;DNKK 	9 	9 88HH 9	D,dC8888		9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9s   >BBBc                 .   | j                                         }t          r| j                             | j                  5  | j                             | j                  r^| j                             | j        d           |t          t          hv s| j	        s | j         
                                 t          t          	 ddd           dS # 1 swxY w Y   dS |t          t          hv s| j	        s | j         
                                 t          t          )at  
        This function is called when the main process sends a kill signal to this process. This can mean two things:
        - Another child process encountered an error in either the init/exit or map function which means we should exit
        - The current task timed out and we should interrupt it

        When on Windows, this function can be invoked when no function is running. This means we will need to check if
        there is a running task and only raise if there is. Otherwise, the exception thrown event will be set and the
        worker will exit gracefully itself.
        
        On other platforms, this signal is only send when either the user defined function, worker init or worker exit
        function is running. In such cases, a StopWorker exception is raised, which is caught by the ``_run_safely()``
        function, so we can quit gracefully.
        FN)r)   get_exception_thrown_job_idr   r   r&   r   set_worker_running_taskr   r   r:   signal_kill_signal_receivedr   r   )r=   r   exception_job_ids      r?   ry   z,AbstractWorker._on_exception_exit_gracefully   sM     ,HHJJ 	&"??OO . .$<<T^LL .%==dneTTT'Iy+AAAI[A)EEGGG((--.. . . . . . . . . . . . . . . . . .  Iy#999AS9!==???  %%s    A>CCCc                    | j                             | j                  r| j                             d          rk| j                             | j                  5  | j                             | j                  rt          j                     ddd           n# 1 swxY w Y   dS | j                             | j                  dS dS )aG  
        Windows doesn't fully support signals as Unix-based systems do. Therefore, we have to work around it. This
        function is started in a thread. We wait for a kill signal (Event object) and interrupt the main thread if we
        got it (derived from https://stackoverflow.com/a/40281422) and only when a function is running. This will raise
        a KeyboardInterrupt, which is then caught by the signal handler, which in turn checks if we need to raise a 
        StopWorker or InterruptWorker. When no function is running, the exception thrown event will be set and the 
        worker will exit gracefully itself.

        Note: functions that release the GIL won't be interupted by this procedure (e.g., time.sleep). If graceful
        shutdown takes too long the process will be terminated by the main process.
        g?)timeoutN)r)   is_worker_aliver&   wait_for_exception_thrownr   r   _threadinterrupt_mainr=   s    r?   r{   z4AbstractWorker._on_exception_exit_gracefully_windows  s    //?? 	 ::3:GG &CCDNSS 1 1(@@PP 1.0001 1 1 1 1 1 1 1 1 1 1 1 1 1 1  //?? 	 	 	 	 	s   3BB Bc                 $   g | _         | j        j        r| j                             | j                   | j        j        $| j                             | j        j                   | j        j        r!| j                             | j                   dS dS )zj
        Gather additional args to pass to the function (worker ID, shared objects, worker state)
        N)r3   r'   pass_worker_idr[   r&   shared_objectsuse_worker_stater2   r   s    r?   rJ   z#AbstractWorker._set_additional_args  s      "* 	8 ''777*6 ''(8(GHHH, 	; ''(9:::::	; 	;r@   FrL   r:   c                     |s | j                                         r| j        n| j        }t	          |t	          |g| j        R            S )a  
        Determine what function to call. If we have to keep in mind the order (for map) we use the helper function with
        idx support which deals with the provided idx variable. However, if we are dealing with an apply function, we
        ignore this as it doesn't matter.

        :param func: Function to call
        :param is_apply_func: Whether this is an apply function
        :return: Function to call
        )r)   
keep_order_helper_func_with_idx_helper_funcr   r3   )r=   rL   r:   helper_funcs       r?   rK   zAbstractWorker._get_func+  sY     :G )4K\KgKgKiKi )t11( 	{GD$H43G$H$H$HIIIr@   re   rb   c                 >   |                      d           |                     d           | j                            | j                   |rM| j        j        r|dk    r|                                  | j        j        r| j        	                                 dS dS dS )ao  
        Force update task insights and progress bar when we got a (non-lethal) poison pill. For a lethal poison pill, we
        run the worker exit function if this worker actually did some work, and wait for the progress bar to be done.
        For a non-lethal poison pill, we simply continue.

        :param lethal: Whether this is a lethal poison pill
        TrC   r   N)
r_   r\   r)   rY   r&   r(   r`   ra   progress_bar#wait_until_progress_bar_is_complete)r=   re   rb   s      r?   rP   z"AbstractWorker._handle_poison_pill9  s     	"""555!!t!444##DN333 	H* &/?!/C/C##%%%+ H!EEGGGGG		H 	HH Hr@   c                    | j                             | j                   | j                             | j                  }|dS || _        |                     | j        j                  }| j                             | j                   |S )z
        Handle new map parameters. This means we need to update the map parameters and get the new function to call.

        :return: Function to call
        N)r)   rY   r&   rO   r(   rK   rL   )r=   r(   rL   s      r?   rU   z%AbstractWorker._handle_new_map_paramsJ  s}     	##DN333&//??
 4$~~do233##DN333r@   NNc                     | j                             | j                   | j                             | j                  }|dS |\  }\  }}|                     |d          }||ff}||fS )z
        Handle apply pill. This means we need to get the next task and return the function to call and the next chunked
        args to process

        :return: Function to call and next chunked args to process
        Nr   T)r:   )r)   rY   r&   rO   rK   )r=   taskrf   rd   rh   rL   rc   s          r?   rV   z!AbstractWorker._handle_apply_pill]  s}     	##DN333 ))$.99 <:%)""T~~j~=="TGO&&&r@   c                      j         rdS  j                             j        t                     t           _         fd} j        j        	  j                             j                    	                    |t                    \  }}}} j        
                     j                   nD#  j        
                     j                   w xY w 	                    |t                    \  }}}}d _         |S )z
        Runs the init function when provided.

        :return: True when the worker needs to shut down, False otherwise
        Fc                      t           j        j         j                  5    j        j         j          d d d            d S # 1 swxY w Y   d S N)r#   r*   worker_init_timer&   r(   rW   r3   r   s   r?   
_init_funcz1AbstractWorker._run_init_func.<locals>._init_func~  s    ,=t~NN C C++T-ABBC C C C C C C C C C C C C C C C C Cs   AA
ANT)r<   r)   signal_worker_working_on_jobr&   r   r;   r(   worker_init_timeoutsignal_worker_init_started_run_safelysignal_worker_init_completed)r=   r   r   rl   s   `   r?   rX   zAbstractWorker._run_init_funcr  s	    # 	566t~yQQQ$	C 	C 	C 	C 	C
 ?.:O!<<T^LLL,0,<,<Z,S,S)1a)!>>t~NNNN!>>t~NNNN(,(8(8Y(O(O%Aq!%#' s   ?B- -!Crf   rh   c                      j         |k    r' j                             j        |           | _          fd}	  j                             j                                        ||          \  }}}} j                             j                   n$#  j                             j                   w xY w||||fS )a  
        Runs the main function when provided.

        :param func: Function to call
        :param job_id: Job ID
        :param args: Args to pass to the function
        :return: Tuple containing results from the function and boolean values indicating whether the function was run
            successfully, whether the results should send on the queue, and indicating whether the worker needs to shut
            down
        c                      t          j        j        j        j        fd          5  j        r  n
           } d d d            n# 1 swxY w Y   j                            j                   | S )Nc                  2                          d          S )Nz | )	separator)_format_args)rh   r=   s   r?   <lambda>z9AbstractWorker._run_func.<locals>._func.<locals>.<lambda>  s     1 1$% 1 H H r@   )r#   r*   worker_working_timer&   r9   r:   update_n_completed_tasks)_resultsrh   rL   r=   s    r?   _funcz'AbstractWorker._run_func.<locals>._func  s    ,@$.RVRmHHHHHJ J M M*.*<L44;;$$t**M M M M M M M M M M M M M M M  99$.IIIOs   AAA)r;   r)   r   r&   signal_worker_task_startedr   signal_worker_task_completed)	r=   rL   rf   rh   r   rg   rj   rk   rl   s	   `` `     r?   rZ   zAbstractWorker._run_func  s     v%%::4>6RRR%D	 	 	 	 	 	 		K88HHH?C?O?OPUW]_c?d?d<GWl,<::4>JJJJD::4>JJJJ/???s   ;B !B:c                 2     j                              j        t                     t           _         fd} j        j        	  j                              j                                        |t                    \  }}}} j         	                     j                   nD#  j         	                     j                   w xY w                     |t                    \  }}}}|rdS |r) j         
                     j        t          d|fg           dS )z
        Runs the exit function when provided and stores its results.

        :return: True when the worker needs to shut down, False otherwise
        c                      t           j        j         j                  5    j        j         j         cd d d            S # 1 swxY w Y   d S r   )r#   r*   worker_exit_timer&   r(   r`   r3   r   s   r?   
_exit_funcz1AbstractWorker._run_exit_func.<locals>._exit_func  s    ,=t~NN J J2t2D4HIJ J J J J J J J J J J J J J J J J Js   AA	ANTF)r)   r   r&   r   r;   r(   worker_exit_timeoutsignal_worker_exit_startedr   signal_worker_exit_completedr]   )r=   r   rg   rj   rk   rl   s   `     r?   ra   zAbstractWorker._run_exit_func  s0    	66t~yQQQ$	J 	J 	J 	J 	J
 ?.:O!<<T^LLLCGCSCST^`iCjCj@,0@!>>t~NNNN!>>t~NNNN?C?O?OPZ\e?f?f<GWl,< 	X4 	X))$.ItW;U:VWWWus   ?B$ $!Cexception_argsc                    | j                                         rdS 	 	 | j                             | j        d            |            }| j                             | j        d           n# t          $ r Y dS t
          t          f$ rk}| j                             | j        d           | j        r!|                     ||          }|dddfcY d}~S | 	                    |||           t          d}~ww xY wn# t          $ r Y dS w xY w|dddfS )ae  
        A rather complex locking and exception mechanism is used here so we can make sure we only raise an exception
        when we should. See `_exit_gracefully` for more information.

        :param func: Function to run
        :param job_id: Job ID
        :param exception_args: Arguments to pass to `_format_args` when an exception occurred
        :return: Tuple containing results from the function and boolean values indicating whether the function was run
            successfully, whether the results should send on the queue, and indicating whether the worker needs to shut
            down
        )NTFTTF)NFFFN)NFFT)r)   rR   r   r&   r   	Exception
SystemExitr:   _get_exceptionr   r   )r=   rL   rf   r   rg   r   	exceptions          r?   r   zAbstractWorker._run_safely  sj    --// 	+**	,% !99$.$OOO$&&!99$.%PPPP" 1 1 1 100z* % % % !99$.%PPP% % $ 3 3NC H HI$eT58888888 KK<<<$$% Q*  	, 	, 	, ,++	, dE))sO   A
A) (C5 )
C13C5 6C1AC,C1	C5 C,,C11C5 5
DDr   c                     | j                                         sV| j                             |           |                     ||          }| j                             | j        |d|fg           dS dS )a  
        Create exception and pass it to the parent process. Let other processes know an exception is set

        :param job_id: Job ID
        :param args: Funtion arguments where exception was raised
        :param err: Exception that should be passed on to parent process
        FN)r)   rR   signal_exception_thrownr   r]   r&   )r=   rf   rh   r   r   s        r?   r   zAbstractWorker._raise   s      1133 		X 55f=== ++D#66I ))$.FE9;U:VWWWWW		X 		Xr@   c                    d| j          d|                     |           dt          j                     }	 t	          j        t          |                     t	          j        |j                   t	          j        |j                   n8# t          j	        t          f$ r t          t          |                    }Y nw xY wt          |          |j        |j        |fS )a  
        Try to pickle the exception and create a traceback string

        :param args: Funtion arguments where exception was raised
        :param err: Exception that was raised
        :return: Tuple containing the exception type, args, state, and a traceback string
        z

Exception occurred in Worker-z with the following arguments:

)r&   r   	traceback
format_excpickledumpstyperh   __dict__PicklingError	TypeErrorr   repr)r=   rh   r   traceback_strs       r?   r   zAbstractWorker._get_exception  s    ODN O O,,T22O O6?6J6L6LO O	8Lc###L"""L&&&&$i0 	8 	8 	8,T#YY77CCC	8 Cyy#(CL-??s   AB
 
2B?>B?r   r   c                    | j         r|\  }}n'|r!| j                                        r|d         n|}d}|                     ||          \  }}g }|                    d t          |          D                        |                    d |                                D                        |                    |          S )z
        Format the function arguments to a string form.

        :param args: Funtion arguments
        :param separator: String to use as separator between arguments
        :return: String containing the task arguments
           Nc                 >    g | ]\  }}d | dt          |           S zArg z: )r   ).0arg_nrargs      r?   
<listcomp>z/AbstractWorker._format_args.<locals>.<listcomp>A  s3    ddd;f;;S		;;dddr@   c                 X    g | ]'\  }}d t          |           dt          |           (S r   )strr   )r   keyvalues      r?   r   z/AbstractWorker._format_args.<locals>.<listcomp>B  s9    fffJC?c#hh??$u++??fffr@   )r:   r)   r   _convert_args_kwargsextend	enumerateitemsjoin)r=   rh   r   	func_argsfunc_kwargsformatted_argss         r?   r   zAbstractWorker._format_args.  s      	%)"I{{#'TD,=,H,H,J,JTQPTIK!%!:!:9k!R!R	; ddyYbOcOcdddeeeffR]RcRcReRefffggg~~n---r@   c                 J    |d         |                      ||d                   fS )a  
        Helper function which calls the function `func` but preserves the order index

        :param func: Function to call each time new task arguments become available
        :param args: Tuple of ``(idx, _args)`` where ``_args`` correspond to the arguments to pass on to the function.
            ``idx`` is used to preserve order
        :return: (idx, result of calling the function with the given arguments) tuple
        r   r   
_call_func)r=   rL   rh   s      r?   r   z$AbstractWorker._helper_func_with_idxF  s%     Awd1g6666r@   kwargsc                 0    |                      |||          S )aa  
        Helper function which calls the function `func`

        :param func: Function to call each time new task arguments become available
        :param args: Arguments to pass on to the function
        :param kwargs: Keyword arguments to pass to the function
        :return: Result of calling the function with the given arguments) tuple
        r   r=   rL   rh   r   s       r?   r   zAbstractWorker._helper_funcQ  s     tT6222r@   c                 D    |                      ||          \  }} ||i |S )aM  
        Helper function which calls the function `func` and passes the arguments in the correct way

        :param func: Function to call each time new task arguments become available
        :param args: Arguments to pass on to the function. If this is a dictionary and kwargs is not provided, then
            these args will be treated as keyword arguments. If this is an iterable, then the arguments will be
            unpacked.
        :param kwargs: Keyword arguments to pass to the function
        :return: Result of calling the function with the given arguments) tuple
        )r   r   s       r?   r   zAbstractWorker._call_func\  s2     00v>>ftT$V$$$r@   c                 
   t          | t                    r|| }d} n`t          | t          j        j                  r>t          | t
          t          f          s"t          rt          | t          j	                  sn| f} |i }| |fS )a  
        Convert the arguments to a tuple and keyword arguments to a dictionary.

        If args is a dictionary and kwargs is not provided, then these args will be treated as keyword arguments. If
        this is an iterable (but not str, bytes, or numpy array), then these arguments will be unpacked.

        :param args: Arguments
        :param kwargs: Keyword arguments
        :return: Args and kwargs
        N )

isinstancedictcollectionsabcIterabler   bytesNUMPY_INSTALLEDnpndarray)rh   r   s     r?   r   z#AbstractWorker._convert_args_kwargsj  s     dD!! 	fnFDD{788 	DSVX]R^A_A_ 	 	%/bj%A%A	5D>FV|r@   rD   c                     | j         j        r;| j                            | j        | j        | j        |          \  | _        | _        dS dS )zg
        Update the progress bar data

        :param force_update: Whether to force an update
        N)r(   r   r)   task_completed_progress_barr&   r5   r6   r=   rD   s     r?   r\   z#AbstractWorker._update_progress_bar  sY     ?' 	484E4a4a >@ceq5 52T+000	 	r@   c                 j    | j                             | j        | j        | j        |          | _        dS )zh
        Update the task insights data

        :param force_update: Whether to force an update
        rC   N)r*   update_task_insightsr&   r7   r9   r   s     r?   r_   z$AbstractWorker._update_task_insights  s=     /3.B.W.WND?A\kw /X /
 /
+++r@   )r.   N)Fr   )r   )2__name__
__module____qualname____doc__intr    r   r   r   r!   r   floatr1   rm   rE   rv   ry   r{   rJ   r   boolrK   rP   r   rU   r   r   r   rV   rX   r
   rZ   ra   r   r   r   r   r   r	   r   r   r   r   r   r   staticmethodr   r\   r_   __classcell__)r>   s   @r?   r%   r%   &   s        &)# &)4D &)Ra &)*&)=K&)*?&) 0J&) X]&) bf&) &) &) &) &) &)PvA vA vA vAp   *9 9 9 9& & & &>   &
; 
; 
; 
;J Jh Jt J J J J JH$ H# H$ H H H H"(:    &'E%#*>j@Q*Q$R ' ' ' '*         :@h @ @Xd^ @X]^acgimos^sXt @ @ @ @>    < VZ3* 3*3*&.sm3*EMc]3*	sD$$	%3* 3* 3* 3*jXXc] X(3- XeIWaLaFb Xgk X X X X*@8C= @uY
=R7S @X]^bdikoqt^tXu @ @ @ @2. .# .3 .# . . . .0	7( 	7%S/ 	7eTWY\T\o 	7 	7 	7 	7	3 	3 	3 	3htn 	3X[ 	3 	3 	3 	3% %x %s %HTN %VY % % % %  3  %PUW[P[J\    \0
 
 
$ 
 
 
 

 
$ 
4 
 
 
 
 
 
 
 
r@   r%   c                       e Zd ZdS )
ForkWorkerNr   r   r   r   r@   r?   r  r            r@   r  mpforkc                       e Zd ZdS )ForkServerWorkerNr  r   r@   r?   r  r    r	  r@   r  
forkserverc                       e Zd ZdS )SpawnWorkerNr  r   r@   r?   r  r            Dr@   r  spawnc                       e Zd ZdS )ThreadingWorkerNr  r   r@   r?   r  r    r  r@   r  ro   c                       e Zd ZdS )DillForkWorkerNr  r   r@   r?   r  r            Dr@   r  c                       e Zd ZdS )DillForkServerWorkerNr  r   r@   r?   r  r    r  r@   r  mp_dillc                       e Zd ZdS )DillSpawnWorkerNr  r   r@   r?   r  r    r	  r@   r  rz   use_dillr.   c                    | dk    rt           S |r|t          st          d          | dk    rt          st	          d          t
          S | dk    rt          st	          d          t          S | dk    rt          S t	          d|  d	          | dk    rt          st	          d          t          S | dk    rt          st	          d          t          S | dk    rt          S t	          d
|  d	          )a  
    Returns the appropriate worker class given the start method

    :param start_method: What Process/Threading start method to use, see the WorkerPool constructor
    :param use_dill: Whether to use dill has serialization backend. Some exotic types (e.g., lambdas, nested functions)
        don't work well when using ``spawn`` as start method. In such cased, use ``dill`` (can be a bit slower
        sometimes)
    :return: Worker class
    ro   zCan't use dill as the dependency "multiprocess" is not installed. Use `pip install mpire[dill]` to install the required dependencyr  z$Start method 'fork' is not availabler  z*Start method 'forkserver' is not availabler  z!Unknown start method with dill: ''zUnknown start method: ')r  DILL_INSTALLEDImportErrorr   
ValueErrorr  r  r  r  r  r  )rz   r  s     r?   worker_factoryr#    s<    {""	 H 	R P Q Q QV##! I !GHHH!!\))! O !MNNN''W$$""PPPPQQQ6!!! I !GHHH\))! O !MNNN##W$$F|FFFGGGr@   )Hcollections.abcr   dillr   r!  multiprocessingr
  rr   r4   r   r   	functoolsr   ro   r   r   r   typingr   r   r	   r
   r   r   r   r   multiprocessr   numpyr   r   mpire.commsr   r   r   r   r   r   r   mpire.contextr   r   r    mpire.dashboard.connection_utilsr   r   mpire.exceptionr   r   r   mpire.insightsr   mpire.paramsr   r    mpire.tqdm_utilsr!   r"   mpire.utilsr#   r%   Processr  r  r  r  r  r  r  r   r  r#  r   r@   r?   <module>r4     s         MMMMM                  9 9 9 9 9 9 9 9 9 9 J J J J J J J J J J J J J J J J J J J JNN   NNNOO   	BOOO& & & & & & & & & & & & & & & & & & F F F F F F F F F F a a a a a a a a S S S S S S S S S S ) ) ) ) ) ) : : : : : : : : ? ? ? ? ? ? ? ?      q	
 q	
 q	
 q	
 q	
 q	
 q	
 q	
h      ^[%6v%>%F       >;t+<\+J+R   	 	 	 	 	.+d"3G"<"D 	 	 		 	 	 	 	nk+&>&E 	 	 	  	 	 	 	 	 	^[->v-F-N 	 	 		 	 	 	 	>;y3I,3W3_ 	 	 	    .+i*@*I*Q   (H (H (HeNTVT^`fDf>g9h (H (H (H (H (H (Hs0    	A A$#A$(A/ /	A;:A;