
    wi                       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mZ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dZY nw xY wd dlmZmZmZmZmZ d dlmZmZmZmZm Z  d dl!m"Z"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. d dl/m0Z0 d dl1m2Z2 d dl3m4Z4m5Z5 d dl6m7Z7m8Z8m9Z9 d dl:m;Z;m<Z<  e j=        e>          Z? G d d          Z@dS )    N)
AnyCallableDict	GeneratorIterableListOptionalSizedUnionTupleTF)AsyncResultAsyncResultTypeAsyncResultWithExceptionGetter UnorderedAsyncExitResultIteratorUnorderedAsyncResultIterator)	EXIT_FUNC	INIT_FUNCMAIN_PROCESSPOISON_PILLWorkerComms)DEFAULT_START_METHODRUNNING_WINDOWS) get_dashboard_connection_details)populate_exception)WorkerInsights)check_map_parametersCPUListWorkerMapParamsWorkerPoolParams)ProgressBarHandler)DisableKeyboardInterruptSignal)get_tqdmTqdmManager)apply_numpy_chunkingchunk_tasksset_cpu_affinity)MP_CONTEXTSworker_factoryc            $          e Zd ZdZddddddeddddfdee         dedede	d	ed
ede
dededededdfdZdGdeddfdZdHde	ddfdZdGd
eddfdZdGdeddfdZdGdeddfdZdIdZdeddfdZdIdZdIdZdIdZdIdZdefdZdJd Zd!e	ddfd"Z	 	 	 	 	 	 	 dKd#ed$eeef         d%ee         d&ee         d'ee         d(ee         d)ee         d*ed+ed,ee         d-ee         d.ee         d/ee         d0ee         d1ee e
e	f                  d2ee
         de	f"d3Z!	 	 	 	 	 	 	 	 dLd#ed$eeef         d%ee         d&ee         d'ee         d(ee         d)ee         d*ed,ee         d-ee         d.ee         d/ee         d0ee         d1ee e
e	f                  d2ee
         de	f d4Z"	 	 	 	 	 	 	 dLd#ed$eeef         d%ee         d&ee         d'ee         d(ee         d)ee         d*ed,ee         d-ee         d.ee         d/ee         d0ee         d1ee e
e	f                  d2ee
         de#e	ddf         f d5Z$	 	 	 	 	 	 	 	 dLd#ed$eeef         d%ee         d&ee         d'ee         d(ee         d)ee         d*ed,ee         d-ee         d.ee         d/ee         d0ee         d1ee e
e	f                  d2ee
         de#e	ddf         f d6Z%	 	 	 	 dMd#ed8e	d9e d:ee         d;ee         d,ee         d-ee         d.ee         d/ee         d0ee         de	fd<Z&	 	 	 	 	 dMd#ed8e	d9e d:ee         d;ee         d,ee         d-ee         d.ee         d/ee         d0ee         de'fd=Z(dId>Z)dNdeddfd?Z*e*Z+dId@Z,dedAe-j.        ddfdBZ/deddfdCZ0dIdDZ1dIdEZ2de fdFZ3dS )O
WorkerPoolzw
    A multiprocessing worker pool which acts like a ``multiprocessing.Pool``, but is faster and has more options.
    NTFn_jobsdaemoncpu_idsshared_objectspass_worker_iduse_worker_statestart_method
keep_aliveuse_dillenable_insightsorder_tasksreturnc                    t          |||||||||	|
|          | _        d| _        t          ||	          | _        |dk    rt
          d         | _        nt
          |	rdnd         |         | _        i | _        t          | j        t                     t          | j        t                     t          | j                   g | _        t          | j        | j        j        | j        j                  | _        d| _        d| _        d| _        d| _        d| _        t-          j                    | _        d| _        t5          | j        | j        j        | j        j                  | _        dS )a  
        :param n_jobs: Number of workers to spawn. If ``None``, will use ``mpire.cpu_count()``
        :param daemon: Whether to start the child processes as daemon
        :param cpu_ids: List of CPU IDs to use for pinning child processes to specific CPUs. The list must be as long as
            the number of jobs used (if ``n_jobs`` equals ``None`` it must be equal to ``mpire.cpu_count()``), or the
            list must have exactly one element. In the former case, element `i` specifies the CPU ID(s) to use for child
            process `i`. In the latter case the single element specifies the CPU ID(s) for all child  processes to use.
            A single element can be either a single integer specifying a single CPU ID, or a list of integers specifying
            that a single child process can make use of multiple CPU IDs. If ``None``, CPU pinning will be disabled
        :param shared_objects: Objects to be passed on as shared objects to the workers once. It will be passed on to
            the target, ``worker_init``, and ``worker_exit`` functions. ``shared_objects`` is only passed on when it's
            not ``None``. Shared objects will be copy-on-write when using ``fork`` as start method. When enabled,
            functions receive the shared objects as second argument, depending on other settings. The order is:
            ``worker_id``, ``shared_objects``, ``worker_state``, and finally the arguments passed on from
            ``iterable_of_args``
        :param pass_worker_id: Whether to pass on a worker ID to the target, ``worker_init``, and ``worker_exit``
            functions. When enabled, functions receive the worker ID as first argument, depending on other settings. The
            order is: ``worker_id``, ``shared_objects``, ``worker_state``, and finally the arguments passed on from
            ``iterable_of_args``
        :param use_worker_state: Whether to let a worker have a worker state. The worker state will be passed on to the
            target, ``worker_init``, and ``worker_exit`` functions. When enabled, functions receive the worker state as
            third argument, depending on other settings. The order is: ``worker_id``,  ``shared_objects``,
            ``worker_state``, and finally the arguments passed on from ``iterable_of_args``
        :param start_method: Which process start method to use. Options for multiprocessing: ``'fork'`` (default, if
            available), ``'forkserver'`` and ``'spawn'`` (default, if ``'fork'`` isn't available). For multithreading
            use ``'threading'``. See https://docs.python.org/3/library/multiprocessing.html#contexts-and-start-methods
            for more information and
            https://docs.python.org/3/library/multiprocessing.html#the-spawn-and-forkserver-start-methods for some
            caveats when using the ``'spawn'`` or ``'forkserver'`` methods
        :param keep_alive: When ``True`` it will keep workers alive after completing a map call, allowing to reuse
            workers
        :param use_dill: Whether to use dill as 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)
        :param enable_insights: Whether to enable worker insights. Might come at a small performance penalty (often
            neglible)
        :param order_tasks: Whether to provide tasks to the workers in order, such that worker 0 will get chunk 0,
            worker 1 will get chunk 1, etc.
        N	threadingmp_dillmpF)r   pool_params
map_paramsr(   Workerr'   ctx_cacher   r   r   r   _workersr   r+   r5   _worker_comms_map_running_results_handler_thread_restart_handler_thread_timeout_handler_thread _unexpected_death_handler_threadr8   Event_handler_threads_stop_event_progress_bar_handlerr   r3   _worker_insights)selfr+   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5   s               b/var/www/development/aibuddy-work/election-extract/venv/lib/python3.11/site-packages/mpire/pool.py__init__zWorkerPool.__init__&   sZ   X ,FGV^Uceu,8*hP_aln n %\8<< ;&&";/DHH"#B99dCLQDH 35&t{LAAA&t{I>>>(555 (43C3JDL\Lhii! (,$'+$'+$04-+4?+<+<( &*" !/tx9I9PRVRbRk l l    pass_onc                 p    || j         j        k    r| j                                         || j         _        dS )a  
        Set whether to pass on the worker ID to the function to be executed or not (default= ``False``).

        :param pass_on: Whether to pass on a worker ID to the target, ``worker_init``, and ``worker_exit``
            functions. When enabled, functions receive the worker ID depending on other settings. The order is:
            ``worker_id``, ``shared_objects``, ``worker_state``, and finally the arguments passed on using
            ``iterable_of_args``
        N)r;   r/   rA   reset)rK   rO   s     rL   pass_on_worker_idzWorkerPool.pass_on_worker_idw   s;     d&555$$&&&*1'''rN   c                 p    || j         j        k    r| j                                         || j         _        dS )ay  
        Set shared objects to pass to the workers.

        :param shared_objects: Objects to be passed on as shared objects to the workers once. It will be passed on to
            the target, ``worker_init``, and ``worker_exit`` functions. ``shared_objects`` is only passed on when it's
            not ``None``. Shared objects will be copy-on-write when using ``fork`` as start method. When enabled,
            functions receive the shared objects depending on other settings. The order is: ``worker_id``,
            ``shared_objects``, ``worker_state``, and finally the arguments passed on using ``iterable_of_args```
        N)r;   r.   rA   rQ   )rK   r.   s     rL   set_shared_objectszWorkerPool.set_shared_objects   s;     T-<<<$$&&&*8'''rN   c                 p    || j         j        k    r| j                                         || j         _        dS )aI  
        Set whether or not each worker should have its own state variable. Each worker has its own state, so it's not
        shared between the workers.

        :param use_worker_state: Whether to let a worker have a worker state. The worker state will be passed on to the
            target, ``worker_init``, and ``worker_exit`` functions. When enabled, functions receive the worker state
            depending on other settings. The order is: ``worker_id``,  ``shared_objects``, ``worker_state``, and finally
            the arguments passed on using ``iterable_of_args``
        N)r;   r0   rA   rQ   )rK   r0   s     rL   set_use_worker_statezWorkerPool.set_use_worker_state   s;     t/@@@$$&&&,<)))rN   c                     || j         _        dS )z
        Set whether workers should be kept alive in between consecutive map calls.

        :param keep_alive: When True it will keep workers alive after completing a map call, allowing to reuse workers
        N)r;   r2   )rK   r2   s     rL   set_keep_alivezWorkerPool.set_keep_alive   s     '1###rN   c                     || j         _        dS )a4  
        Set whether to provide tasks to the workers in order, such that worker 0 will get chunk 0, worker 1 will get
        chunk 1, etc.

        :param order_tasks: Whether to provide tasks to the workers in order, such that worker 0 will get chunk 0,
            worker 1 will get chunk 1, etc.
        N)r;   r5   )rK   r5   s     rL   set_order_taskszWorkerPool.set_order_tasks   s     (3$$$rN   c                    | j         t                                                    | j         t                                                    | j         t                                                    | j                                         | j                            | j	        j
                   dg| j	        j        z  | _        t          | j	        j                  D ]}|                     |           | j                                         t#          j        | j        d          | _        t#          j        | j        d          | _        t#          j        | j        d          | _        t#          j        | j        d          | _        | j                                         | j                                         | j                                         | j                                         dS )zl
        Spawns the workers and starts them so they're ready to start reading from the tasks queue.
        NT)targetr,   )r?   r   rQ   r   r   rA   
init_commsrJ   reset_insightsr;   r4   r+   r@   range_start_workerrH   clearr8   Thread_results_handlerrC   _restart_handlerrD   _timeout_handlerrE   _unexpected_death_handlerrF   startrK   	worker_ids     rL   _start_workerszWorkerPool._start_workers   s    	L!'')))I$$&&&I$$&&& 	%%''',,T-=-MNNN !1!88t/677 	* 	*Iy)))) 	(..000'0'7t?T]a'b'b'b$'0'7t?T]a'b'b'b$'0'7t?T]a'b'b'b$090@Hfos0t0t0t-$**,,,$**,,,$**,,,-3355555rN   ri   c                 :   t                      5  |                     || j        | j        | j        | j        t          j                    t                      t          j	                              | j
        |<   | j        j        | j
        |         _        d| | j
        |         _        | j
        |                                          ddd           n# 1 swxY w Y   | j        j        r2t          | j
        |         j        | j        j        |                    dS dS )z
        Creates and starts a single worker

        :param worker_id: ID of the worker
        :return: Worker instance
        Worker-N)r!   r=   r;   r<   rA   rJ   r#   get_connection_detailsr   timer@   r,   namerg   r-   r&   pidrh   s     rL   r`   zWorkerPool._start_worker   sG    ,-- 	- 	-'+{{4+T_d>PRVRg2446V6X6XZ^ZcZeZe( (DM)$ /3.>.EDM)$+,Ai,A,ADM)$)M)$**,,,	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- # 	`T]9594;K;ST];^_____	` 	`s   B7CCCc                    	 | j                             d          }|D ]\  }}}t          |t                    r|t          k    r dS 	 |r#| j        |                             d|           n}t          | \  }}||_        |t          k    r5t          | j                                                  t          t          hz
  n|h}|D ]$}| j        |                             d|           %# t          $ r Y w xY w)z
        Listen for results from the workers and add it to the cache. Note that when ``set`` is called on a result
        object, the result is automatically removed from the cache.
        T)blockNsuccessresultF)rA   get_results
isinstancestrr   r?   _setr   	__cause__r   setkeysr   r   KeyError)	rK   results_batchjob_idrt   ru   errtraceback_errjob_ids_job_ids	            rL   rc   zWorkerPool._results_handler   s=   
	 .:::FFM+8  ' fc** v/D/DFF QF+00f0MMMM-?-H*](5 ]cfo\o\oC(8(8(:(:$;$;|Y>W$W$W$*8  '. Q QG K055eC5PPPP    D	+	s   	B"C,,
C98C9c                 <   | j                                         s| j                                        s| j                                         D ]}| j                                         s| j                                        r dS 	 | j        |                                          n# t          $ r Y nw xY w| j                             |           | 	                    |           | j                                         s| j                                        dS dS dS dS )zH
        Listen for worker restarts and restart them if needed.
        N)
rA   exception_thrownrH   is_setget_worker_restartsr@   joinOSErrorreset_worker_restartr`   rh   s     rL   rd   zWorkerPool._restart_handler  sM    $5577 	.@`@g@g@i@i 	.!/CCEE . .	 %6688 D<\<c<c<e<e FFM),113333   D
 "77	BBB""9----' $5577 	.@`@g@g@i@i 	. 	. 	. 	. 	. 	. 	. 	. 	.s   B$$
B10B1c                 0   | j                                         sw| j                                        s_t	          t          | j                            D ]}	 | j                             |          o| j        |                                          }n# t          $ r d}Y nw xY w|r| j         
                    |          }| j                             |           t          d| d          }t          | j                                                  t           hz
  }|D ]$}| j        |                             d|           % dS t%          j        d           | j                                         s | j                                        [dS dS dS dS )aC  
        Checks that workers that are supposed to be alive, are actually alive. If not, then a worker died unexpectedly.
        Terminate signals are handled by workers themselves, but if a worker dies for any other reason, then we need
        to handle it here.

        Note that a worker can be alive, but their alive status is still False. This doesn't really matter, because we
        know the worker is alive according to the OS. The only way we know that something bad happened is when a worker
        is supposed to be alive but according to the OS it's not.
        Frl   z died unexpectedlyrs   N皙?)rA   r   rH   r   r_   lenr@   is_worker_aliveis_alive
ValueErrorget_worker_working_on_jobsignal_exception_thrownRuntimeErrorr{   r?   r|   r   ry   rn   sleep)rK   ri   worker_diedr   r   r   s         rL   rf   z$WorkerPool._unexpected_death_handler  s    $5577 	@`@g@g@i@i 	 #3t}#5#566  	(#'#5#E#Ei#P#P $K'+}Y'?'H'H'J'J#J  K! ( ( ("'KKK(  !/II)TTF&>>vFFF&'N'N'N'NOOC "$+"2"2"4"455FG") L LF+00s0KKKKFF JsOOO3 $5577 	@`@g@g@i@i 	 	 	 	 	 	 	 	 	s   :BB#"B#c           
          dt           t          t          t                   t          t
          t          gt          f         f         f fd}dt           t          t          t                   t          t
          t          gt          f         f         f fd}dt           t          t          t                   t          t
          t          gt          f         f         f fd} j                                        sD j	        
                                s, j        j        c j        j        Wt          d  j                                                                        D                       rt%          j        d           t)           j        j                  D ]W} j                            |          t0          k    r |            \  }}}n)t2          k    r |            \  }}}n |          \  }}}| |||          rt0          t2          hv pt5           j                 t6                    }|r j                                                            |           t=          d| d	| d
| d          }	t0          k    r5t?           j                                                   tB          t2          hz
  nh}
|
D ]$ j                 "                    d|	           %|r dS Yt%          j        d            j                                        s  j	        
                                (dS dS dS dS )zA
        Check for worker_init/task/worker_exit timeouts
        r6   c                  6    d j         j         j        j        fS )Nworker_init)r<   worker_init_timeoutrA   has_worker_init_timed_outrK   s   rL   _get_init_configz5WorkerPool._timeout_handler.<locals>._get_init_configF       $/"EtGYGsssrN   c                  6    d j         j         j        j        fS )Nworker_exit)r<   worker_exit_timeoutrA   has_worker_exit_timed_outr   s   rL   _get_exit_configz5WorkerPool._timeout_handler.<locals>._get_exit_configI  r   rN   c                     	 dj                  j        j        j        fS # t          $ r dd j        j        fcY S w xY w)Ntask)r?   _timeoutrA   has_worker_task_timed_outr}   )r   r   rK   s    rL   _get_task_configz5WorkerPool._timeout_handler.<locals>._get_task_configL  s^    Rt{62;T=O=iii R R RtT%7%QQQQQRs   " >>Nc              3   (   K   | ]}|j         d u V  d S N)r   ).0jobs     rL   	<genexpr>z.WorkerPool._timeout_handler.<locals>.<genexpr>X  s)      TT,TTTTTTrN   r   rl    z timed out (timeout=)Frs   )#r   rx   r	   floatr   intboolrA   r   rH   r   r<   r   r   allr?   copyvaluesrn   r   r_   r;   r+   r   r   r   rw   r   r   _send_kill_signal_to_workerTimeoutErrorr{   r|   r   ry   )rK   r   r   r   ri   timeout_func_nametimeout_varhas_timed_out_func	kill_poolr   r   r   s   `          @rL   re   zWorkerPool._timeout_handlerB  s   	t%Xe_hU|UYGY>Z(Z"[ 	t 	t 	t 	t 	t 	t	t%Xe_hU|UYGY>Z(Z"[ 	t 	t 	t 	t 	t 	t	RsHUOXsTYl\`N`Ea/a)b 	R 	R 	R 	R 	R 	R 	R $5577 .	@`@g@g@i@i .	 3;O7?TT8H8H8J8J8Q8Q8S8STTTTT @ 
3"4#3#:;;  	+EEiPPY&&IYIYI[I[F%{4F4Fy((IYIYI[I[F%{4F4FIYIYZ`IaIaF%{4F */A/A)[/Y/Y*
 9i"88 V"4;v#68TUU  ! K*BB6JJJ44Y??? ''r'r'r=N'r'rdo'r'r'rssCW]ajWjWjs4;#3#3#5#566,	9RRRqwpxG") L LF+00s0KKKK   JsOOO] $5577 .	@`@g@g@i@i .	 .	 .	 .	 .	 .	 .	 .	 .	rN   c                 J    | j         t                                                   S )zu
        Obtain a list of exit results when an exit function is defined.

        :return: Exit results list
        )r?   r   rv   r   s    rL   get_exit_resultszWorkerPool.get_exit_results  s     {9%11333rN   c                     | S )z;
        Enable the use of the ``with`` statement.
         r   s    rL   	__enter__zWorkerPool.__enter__  s	     rN   _c                 .    |                                   dS )zk
        Enable the use of the ``with`` statement. Gracefully terminates workers, if there are any
        N)	terminate)rK   r   s     rL   __exit__zWorkerPool.__exit__  s     	rN   funciterable_of_argsiterable_lenmax_tasks_active
chunk_sizen_splitsworker_lifespanprogress_barconcatenate_numpy_outputr   r   task_timeoutr   r   progress_bar_optionsprogress_bar_stylec                 \   | j                                          t          r<t          |t          j                  r"t          ||||| j        j                  \  }}}}|t          |d          rt          |          }|                     |d t          |          D             |||||||
||||||          }| j                                          d t          |d           D             }t          r8|r6|	r4t          |d         t          j                  rt	          j        |          n|S )ax  
        Same as ``multiprocessing.map()``. Also allows a user to set the maximum number of tasks available in the queue.
        Note that this function can be slower than the unordered version.

        :param func: Function to call each time new task arguments become available. When passing on the worker ID the
            function should receive the worker ID as its first argument. If shared objects are provided the function
            should receive those as the next argument. If the worker state has been enabled it should receive a state
            variable as the next argument
        :param iterable_of_args: A numpy array or an iterable containing tuples of arguments to pass to a worker, which
            passes it to the function ``func``
        :param iterable_len: Number of elements in the ``iterable_of_args``. When chunk_size is set to ``None`` it needs
            to know the number of tasks. This can either be provided by implementing the ``__len__`` function on the
            iterable object, or by specifying the number of tasks
        :param max_tasks_active: Maximum number of active tasks in the queue. If ``None`` it will be converted to
            ``n_jobs * chunk_size * 2``
        :param chunk_size: Number of simultaneous tasks to give to a worker. When ``None`` it will use ``n_splits``.
        :param n_splits: Number of splits to use when ``chunk_size`` is ``None``. When both ``chunk_size`` and
            ``n_splits`` are ``None``, it will use ``n_splits = n_jobs * 64``.
        :param worker_lifespan: Number of tasks a worker can handle before it is restarted. If ``None``, workers will
            stay alive the entire time. Use this when workers use up too much memory over the course of time
        :param progress_bar: When ``True`` it will display a progress bar
        :param concatenate_numpy_output: When ``True`` it will concatenate numpy output to a single numpy array
        :param worker_init: Function to call each time a new worker starts. When passing on the worker ID the function
            should receive the worker ID as its first argument. If shared objects are provided the function should
            receive those as the next argument. If the worker state has been enabled it should receive a state variable
            as the next argument
        :param worker_exit: Function to call each time a worker exits. Return values will be fetched and made available
            through :obj:`mpire.WorkerPool.get_exit_results`. When passing on the worker ID the function should receive
            the worker ID as its first argument. If shared objects are provided the function should receive those as the
            next argument. If the worker state has been enabled it should receive a state variable as the next argument
        :param task_timeout: Timeout in seconds for a single task. When the timeout is exceeded, MPIRE will raise a
            ``TimeoutError``. Use ``None`` to disable (default). Note: the timeout doesn't apply to ``worker_init`` and
            ``worker_exit`` functions, use `worker_init_timeout` and `worker_exit_timeout` for that, respectively
        :param worker_init_timeout: Timeout in seconds for the ``worker_init`` function. When the timeout is exceeded,
            MPIRE will raise a ``TimeoutError``. Use ``None`` to disable (default).
        :param worker_exit_timeout: Timeout in seconds for the ``worker_exit`` function. When the timeout is exceeded,
            MPIRE will raise a ``TimeoutError``. Use ``None`` to disable (default).
        :param progress_bar_options: Dictionary containing keyword arguments to pass to the ``tqdm`` progress bar. See
            ``tqdm.tqdm()`` for details. The arguments ``total`` and ``leave`` will be overwritten by MPIRE.
        :param progress_bar_style: The progress bar style to use. Can be one of ``None``, ``'std'``, or ``'notebook'``
        :return: List with ordered results
        N__len__c              3   $   K   | ]\  }}||fV  d S r   r   r   args_idxargss      rL   r   z!WorkerPool.map.<locals>.<genexpr>  s+      VV$Hd#VVVVVVrN   c                     g | ]
}|d          S )   r   )r   ru   s     rL   
<listcomp>z"WorkerPool.map.<locals>.<listcomp>  s    ```&)```rN   c                     | d         S )Nr   r   )ru   s    rL   <lambda>z WorkerPool.map.<locals>.<lambda>  s    U[\]U^ rN   )keyr   )rA   signal_keep_orderNUMPY_INSTALLEDrw   npndarrayr$   r;   r+   hasattrr   map_unordered	enumerateclear_keep_ordersortedconcatenate)rK   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   resultssorted_resultss                      rL   mapzWorkerPool.map  ss   d 	,,...  	qz*:BJGG 	qCWXhjvXbdlX\XhXoDq Dq@lJ
 G,<i$H$H/00L$$VV)DT:U:UVVVXdfv/<k[g!46JL^
 
 	++--- a`&F^F^2_2_2_``` 3B Nn NYq N>!,bj99N~...?M	OrN   c                 b    t          |                     |||||||||	|
|||||                    S )a  
        Same as ``multiprocessing.map()``, but unordered. Also allows a user to set the maximum number of tasks
        available in the queue.

        :param func: Function to call each time new task arguments become available. When passing on the worker ID the
            function should receive the worker ID as its first argument. If shared objects are provided the function
            should receive those as the next argument. If the worker state has been enabled it should receive a state
            variable as the next argument
        :param iterable_of_args: A numpy array or an iterable containing tuples of arguments to pass to a worker, which
            passes it to the function ``func``
        :param iterable_len: Number of elements in the ``iterable_of_args``. When chunk_size is set to ``None`` it needs
            to know the number of tasks. This can either be provided by implementing the ``__len__`` function on the
            iterable object, or by specifying the number of tasks
        :param max_tasks_active: Maximum number of active tasks in the queue. If ``None`` it will be converted to
            ``n_jobs * chunk_size * 2``
        :param chunk_size: Number of simultaneous tasks to give to a worker. When ``None`` it will use ``n_splits``.
        :param n_splits: Number of splits to use when ``chunk_size`` is ``None``. When both ``chunk_size`` and
            ``n_splits`` are ``None``, it will use ``n_splits = n_jobs * 64``.
        :param worker_lifespan: Number of tasks a worker can handle before it is restarted. If ``None``, workers will
            stay alive the entire time. Use this when workers use up too much memory over the course of time
        :param progress_bar: When ``True`` it will display a progress bar
        :param worker_init: Function to call each time a new worker starts. When passing on the worker ID the function
            should receive the worker ID as its first argument. If shared objects are provided the function should
            receive those as the next argument. If the worker state has been enabled it should receive a state variable
            as the next argument
        :param worker_exit: Function to call each time a worker exits. Return values will be fetched and made available
            through :obj:`mpire.WorkerPool.get_exit_results`. When passing on the worker ID the function should receive
            the worker ID as its first argument. If shared objects are provided the function should receive those as the
            next argument. If the worker state has been enabled it should receive a state variable as the next argument
        :param task_timeout: Timeout in seconds for a single task. When the timeout is exceeded, MPIRE will raise a
            ``TimeoutError``. Use ``None`` to disable (default). Note: the timeout doesn't apply to ``worker_init`` and
            ``worker_exit`` functions, use `worker_init_timeout` and `worker_exit_timeout` for that, respectively
        :param worker_init_timeout: Timeout in seconds for the ``worker_init`` function. When the timeout is exceeded,
            MPIRE will raise a ``TimeoutError``. Use ``None`` to disable (default).
        :param worker_exit_timeout: Timeout in seconds for the ``worker_exit`` function. When the timeout is exceeded,
            MPIRE will raise a ``TimeoutError``. Use ``None`` to disable (default).
        :param progress_bar_options: Dictionary containing keyword arguments to pass to the ``tqdm`` progress bar. See
            ``tqdm.tqdm()`` for details. The arguments ``total`` and ``leave`` will be overwritten by MPIRE.
        :param progress_bar_style: The progress bar style to use. Can be one of ``None``, ``'std'``, or ``'notebook'``
        :return: List with unordered results
        )listimap_unordered)rK   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   s                   rL   r   zWorkerPool.map_unordered  sR    f D''.>N^`j(0/<Q\^i(46IK^`t(:< < = = 	=rN   c              #     K   | j                                          t          r<t          |t          j                  r"t          ||||| j        j                  \  }}}}d}i }|t          |d          rt          |          }|                     |d t          |          D             |||||||	|
|||||          D ]>\  }}	 ||v r|                    |          V  |dz  }nn#||k    r
|V  |dz  }9|||<   ?t          |                                          D ]}|                    |          V  | j                                          dS )a  
        Same as ``multiprocessing.imap_unordered()``, but ordered. Also allows a user to set the maximum number of
        tasks available in the queue.

        :param func: Function to call each time new task arguments become available. When passing on the worker ID the
            function should receive the worker ID as its first argument. If shared objects are provided the function
            should receive those as the next argument. If the worker state has been enabled it should receive a state
            variable as the next argument
        :param iterable_of_args: A numpy array or an iterable containing tuples of arguments to pass to a worker, which
            passes it to the function ``func``
        :param iterable_len: Number of elements in the ``iterable_of_args``. When chunk_size is set to ``None`` it needs
            to know the number of tasks. This can either be provided by implementing the ``__len__`` function on the
            iterable object, or by specifying the number of tasks
        :param max_tasks_active: Maximum number of active tasks in the queue. If ``None`` it will be converted to
            ``n_jobs * chunk_size * 2``
        :param chunk_size: Number of simultaneous tasks to give to a worker. When ``None`` it will use ``n_splits``.
        :param n_splits: Number of splits to use when ``chunk_size`` is ``None``. When both ``chunk_size`` and
            ``n_splits`` are ``None``, it will use ``n_splits = n_jobs * 64``.
        :param worker_lifespan: Number of tasks a worker can handle before it is restarted. If ``None``, workers will
            stay alive the entire time. Use this when workers use up too much memory over the course of time
        :param progress_bar: When ``True`` it will display a progress bar
        :param worker_init: Function to call each time a new worker starts. When passing on the worker ID the function
            should receive the worker ID as its first argument. If shared objects are provided the function should
            receive those as the next argument. If the worker state has been enabled it should receive a state variable
            as the next argument
        :param worker_exit: Function to call each time a worker exits. Return values will be fetched and made available
            through :obj:`mpire.WorkerPool.get_exit_results`. When passing on the worker ID the function should receive
            the worker ID as its first argument. If shared objects are provided the function should receive those as the
            next argument. If the worker state has been enabled it should receive a state variable as the next argument
        :param task_timeout: Timeout in seconds for a single task. When the timeout is exceeded, MPIRE will raise a
            ``TimeoutError``. Use ``None`` to disable (default). Note: the timeout doesn't apply to ``worker_init`` and
            ``worker_exit`` functions, use `worker_init_timeout` and `worker_exit_timeout` for that, respectively
        :param worker_init_timeout: Timeout in seconds for the ``worker_init`` function. When the timeout is exceeded,
            MPIRE will raise a ``TimeoutError``. Use ``None`` to disable (default).
        :param worker_exit_timeout: Timeout in seconds for the ``worker_exit`` function. When the timeout is exceeded,
            MPIRE will raise a ``TimeoutError``. Use ``None`` to disable (default).
        :param progress_bar_options: Dictionary containing keyword arguments to pass to the ``tqdm`` progress bar. See
            ``tqdm.tqdm()`` for details. The arguments ``total`` and ``leave`` will be overwritten by MPIRE.
        :param progress_bar_style: The progress bar style to use. Can be one of ``None``, ``'std'``, or ``'notebook'``
        :return: Generator yielding ordered results
        r   Nr   c              3   $   K   | ]\  }}||fV  d S r   r   r   s      rL   r   z"WorkerPool.imap.<locals>.<genexpr>Y  sF       =] =]R`RZ\`h=M =] =] =] =] =] =]rN   Tr   )rA   r   r   rw   r   r   r$   r;   r+   r   r   r   r   popr   r|   r   )rK   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   next_result_idxtmp_results
result_idxru   s                       rL   imapzWorkerPool.imap  s     b 	,,...  	qz*:BJGG 	qCWXhjvXbdlX\XhXoDq Dq@lJ
 G,<i$H$H/00L"&"5"5d =] =]@IJZ@[@[=] =] =]^j6F
T\^m6BKQ\^j6IK^`t6H#J #J 	1 	1J"k11%///:::::#q(OO _,,1$ +1J'' !!1!1!3!344 	. 	.J//*------ 	++-----rN   c              #     K   g }d}t           r>t          |t          j                  r$t	          ||||| j        j                  \  }}}}d}t          | j        ||||||||||||          \  }}}}}t          ||	|
|||||          }|st          ||||          }t          |          }|                                }d}d}	 | j        rg| j                            t                     | j        t                                       dt%          d                     |                                  d| _        |rt)          j        | j        j                  }| j        rI| j                                        s0t2                              d           |                     d           | j        r,| j        |k    r!|| _        | j                            |           | j        s|| _        |                                  t?          | j        ||          }|j         }tC          | j        | j        |||| j        | j"                  5 | _#        	 d	}d	}	 	 tI          |          }|tK          |          z  }n# tL          $ r Y nw xY w| j        '                                sz|tK          |          z   |k    rd	 |$                    dd
          V  |dz  }n# tP          j)        $ r Y nw xY w| j        '                                s|tK          |          z   |k    d| j        '                                rn/| j        *                    ||           |tK          |          z  }| j        '                                s/|+                    |           | j#        ,                    |           | j        '                                sT	 |$                    dd          V  n # tP          j)        $ r Y ntL          $ r Y nw xY w| j        '                                T| j        '                                r|                                  |                     | j        j-                   |r| j        .                                 n$# t^          $ r |                                  Y nw xY wddd           n# 1 swxY w Y   |r(|0                    |           t)          j1                     ||2                                 d| _#        d| _        | j        3                                 nl# |r(|0                    |           t)          j1                     ||2                                 d| _#        d| _        | j        3                                 w xY w| j        j4        r3t2          5                    | j"        6                                           dS dS )a  
        Same as ``multiprocessing.imap_unordered()``. Also allows a user to set the maximum number of tasks available in
        the queue.

        :param func: Function to call each time new task arguments become available. When passing on the worker ID the
            function should receive the worker ID as its first argument. If shared objects are provided the function
            should receive those as the next argument. If the worker state has been enabled it should receive a state
            variable as the next argument
        :param iterable_of_args: A numpy array or an iterable containing tuples of arguments to pass to a worker, which
            passes it to the function ``func``
        :param iterable_len: Number of elements in the ``iterable_of_args``. When chunk_size is set to ``None`` it needs
            to know the number of tasks. This can either be provided by implementing the ``__len__`` function on the
            iterable object, or by specifying the number of tasks
        :param max_tasks_active: Maximum number of active tasks in the queue. If ``None`` it will be converted to
            ``n_jobs * chunk_size * 2``
        :param chunk_size: Number of simultaneous tasks to give to a worker. When ``None`` it will use ``n_splits``.
        :param n_splits: Number of splits to use when ``chunk_size`` is ``None``. When both ``chunk_size`` and
            ``n_splits`` are ``None``, it will use ``n_splits = n_jobs * 64``.
        :param worker_lifespan: Number of tasks a worker can handle before it is restarted. If ``None``, workers will
            stay alive the entire time. Use this when workers use up too much memory over the course of time
        :param progress_bar: When ``True`` it will display a progress bar
        :param worker_init: Function to call each time a new worker starts. When passing on the worker ID the function
            should receive the worker ID as its first argument. If shared objects are provided the function should
            receive those as the next argument. If the worker state has been enabled it should receive a state variable
            as the next argument
        :param worker_exit: Function to call each time a worker exits. Return values will be fetched and made available
            through :obj:`mpire.WorkerPool.get_exit_results`. When passing on the worker ID the function should receive
            the worker ID as its first argument. If shared objects are provided the function should receive those as the
            next argument. If the worker state has been enabled it should receive a state variable as the next argument
        :param task_timeout: Timeout in seconds for a single task. When the timeout is exceeded, MPIRE will raise a
            ``TimeoutError``. Use ``None`` to disable (default). Note: the timeout doesn't apply to ``worker_init`` and
            ``worker_exit`` functions, use `worker_init_timeout` and `worker_exit_timeout` for that, respectively
        :param worker_init_timeout: Timeout in seconds for the ``worker_init`` function. When the timeout is exceeded,
            MPIRE will raise a ``TimeoutError``. Use ``None`` to disable (default).
        :param worker_exit_timeout: Timeout in seconds for the ``worker_exit`` function. When the timeout is exceeded,
            MPIRE will raise a ``TimeoutError``. Use ``None`` to disable (default).
        :param progress_bar_options: Dictionary containing keyword arguments to pass to the ``tqdm`` progress bar. See
            ``tqdm.tqdm()`` for details. The arguments ``total`` and ``leave`` will be overwritten by MPIRE.
        :param progress_bar_style: The progress bar style to use. Can be one of ``None``, ``'std'``, or ``'notebook'``
        :return: Generator yielding unordered results
        FTNz0Cannot call 'map' while another 'map' is runningrs   zHWorkerPool parameters changed while keep_alive=True. Restarting workers.r2   timeoutr   {Gz?)rr   r   r   r   )7r   rw   r   r   r$   r;   r+   r   r   r%   r"   get_lockrB   rA   r   r   r?   ry   r   _handle_exceptionr#   start_managerr3   r@   is_initializedloggerwarningstop_and_joinr<   add_new_map_paramsrj   r   r   r    rJ   rI   nextr   StopIterationr   queueEmptyadd_task
set_lengthset_new_totalr2   #wait_until_progress_bar_is_completeKeyboardInterruptset_lockstop_managerremove_from_cachereset_progressr4   debugget_insights_string)rK   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   iterator_of_chunked_argsnumpy_chunkingn_tasksnew_map_paramstqdmoriginal_tqdm_locktqdm_manager_ownerimap_iteratorr   n_activechunk_of_taskss                              rL   r   zWorkerPool.imap_unorderedx  s     f $&  	"z*:BJGG 	"K_ ,
HdFVF]L LH$lJ "N Ui.>NPZ\dfu.0BLReU
 U
Q!:|=Q
 ){KZfht)<>QS S  	d'23CWjZb'c'c$ *++!]]__"c	0  )"::<HHHL)..u6BCu6v6v / x x x&&((( $D  Z%0%>t?O?X%Y%Y" } 5T%7%F%F%H%H 5ijjj""e"444} F$/^"C"C"0"55nEEE= &"0##%%% 9gWcdddM")F $D$4do|Ui$68J$($9; ; 8->B>X5- HG8"-12J-K-KN#s>':'::GG, " " "!E" $(#5#F#F#H#H %'#n*=*==@PPP%&3&8&8tT&8&R&R R R R (A#(; % % % $% $(#5#F#F#H#H %'#n*=*==@PPP  ->>@@ "!*33FNKKK C$7$77/84  ->>@@ J%009992@@III"0AACC """/"4"44"4"M"MMMMM${ ! ! ! D, " " "!E" #0AACC " )::<< 1..000 &&$2B2M&NNN $ Q*NNPPP( - - -**,,,,,-o8- 8- 8- 8- 8- 8- 8- 8- 8- 8- 8- 8- 8- 8- 8-v " +0111(***(//111)-D& %D--//// " +0111(***(//111)-D& %D--//// + 	FLL.BBDDEEEEE	F 	Fs   FT! R.Q>!I43Q>4
J>Q> J2Q>4KQ>K%"Q>$K%%CQ>OQ>O9+Q>-	O96Q>8O99BQ>=R.>RR.RR."T! .R22T! 5R26T! !A)V
r   r   kwargscallbackerror_callbackc                 b    |                      |||||||||	|

  
                                        S )a
  
        Apply a function to a single task. This is a blocking call.

        :param func: Function to apply to the task. When passing on the worker ID the function should receive the
            worker ID as its first argument. If shared objects are provided the function should receive those as the
            next argument. If the worker state has been enabled it should receive a state variable as the next argument
        :param args: Arguments to pass to a worker, which passes it to the function ``func`` as ``func(*args)``
        :param kwargs: Keyword arguments to pass to a worker, which passes it to the function ``func`` as
            ``func(**kwargs)``
        :param callback: Callback function to call when the task is finished. The callback function receives the output
            of the function ``func`` as its argument
        :param error_callback: Callback function to call when the task has failed. The callback function receives the
            exception as its argument
        :param worker_init: Function to call each time a new worker starts. When passing on the worker ID the function
            should receive the worker ID as its first argument. If shared objects are provided the function should
            receive those as the next argument. If the worker state has been enabled it should receive a state variable
            as the next argument
        :param worker_exit: Function to call each time a worker exits. Return values will be fetched and made available
            through :obj:`mpire.WorkerPool.get_exit_results`. When passing on the worker ID the function should receive
            the worker ID as its first argument. If shared objects are provided the function should receive those as the
            next argument. If the worker state has been enabled it should receive a state variable as the next argument
        :param task_timeout: Timeout in seconds for a single task. When the timeout is exceeded, MPIRE will raise a
            ``TimeoutError``. Use ``None`` to disable (default). Note: the timeout doesn't apply to ``worker_init`` and
            ``worker_exit`` functions, use `worker_init_timeout` and `worker_exit_timeout` for that, respectively
        :param worker_init_timeout: Timeout in seconds for the ``worker_init`` function. When the timeout is exceeded,
            MPIRE will raise a ``TimeoutError``. Use ``None`` to disable (default).
        :param worker_exit_timeout: Timeout in seconds for the ``worker_exit`` function. When the timeout is exceeded,
            MPIRE will raise a ``TimeoutError``. Use ``None`` to disable (default).
        :return: Result of the function ``func`` applied to the task
        )apply_asyncget)rK   r   r   r  r  r  r   r   r   r   r   s              rL   applyzWorkerPool.apply0  sD    D dFHnk[f ,.ACVX XX[X[X]X]	^rN   c           
          | j         s/t          |||dd||	|
          | _        |                                  t	          | j        |||          }| j                            |j        |||           |S )a
  
        Apply a function to a single task. This is a non-blocking call.

        :param func: Function to apply to the task. When passing on the worker ID the function should receive the
            worker ID as its first argument. If shared objects are provided the function should receive those as the
            next argument. If the worker state has been enabled it should receive a state variable as the next argument
        :param args: Arguments to pass to a worker, which passes it to the function ``func`` as ``func(*args)``
        :param kwargs: Keyword arguments to pass to a worker, which passes it to the function ``func`` as
            ``func(**kwargs)``
        :param callback: Callback function to call when the task is finished. The callback function receives the output
            of the function ``func`` as its argument
        :param error_callback: Callback function to call when the task has failed. The callback function receives the
            exception as its argument
        :param worker_init: Function to call each time a new worker starts. When passing on the worker ID the function
            should receive the worker ID as its first argument. If shared objects are provided the function should
            receive those as the next argument. If the worker state has been enabled it should receive a state variable
            as the next argument
        :param worker_exit: Function to call each time a worker exits. Return values will be fetched and made available
            through :obj:`mpire.WorkerPool.get_exit_results`. When passing on the worker ID the function should receive
            the worker ID as its first argument. If shared objects are provided the function should receive those as the
            next argument. If the worker state has been enabled it should receive a state variable as the next argument
        :param task_timeout: Timeout in seconds for a single task. When the timeout is exceeded, MPIRE will raise a
            ``TimeoutError``. Use ``None`` to disable (default). Note: the timeout doesn't apply to ``worker_init`` and
            ``worker_exit`` functions, use `worker_init_timeout` and `worker_exit_timeout` for that, respectively
        :param worker_init_timeout: Timeout in seconds for the ``worker_init`` function. When the timeout is exceeded,
            MPIRE will raise a ``TimeoutError``. Use ``None`` to disable (default).
        :param worker_exit_timeout: Timeout in seconds for the ``worker_exit`` function. When the timeout is exceeded,
            MPIRE will raise a ``TimeoutError``. Use ``None`` to disable (default).
        :return: Result of the function ``func`` applied to the task
        NFr   )	r@   r   r<   rj   r   r?   rA   add_apply_taskr   )rK   r   r   r  r  r  r   r   r   r   r   ru   s               rL   r  zWorkerPool.apply_asyncU  s    H } 	"-dKdTY[g.ACVX XDO!!! T[(NLYYY))&-tVLLLrN   c                    | j                                         r>| j        | j                                                                                  }|j        }n/| j                             t                     t                      }|}| j	        M| j	        
                    |p|           | j	        j        %| j	        j                                         d| _	        |                                  | j                                          |)zM
        Handles exceptions thrown by workers and KeyboardInterrupts
        N)rA   r   r?   get_exception_thrown_job_idget_exceptionrz   r   r   r  rI   set_exceptionthreadr   r   r   )rK   	exceptioncauses      rL   r   zWorkerPool._handle_exception  s    
 ..00 	D$6$R$R$T$TUcceeI'EE66|DDD)++IE
 %1&44U5GiHHH)0<*166888-1* 	++--- rN   c                    | j         rC|r| j                                         n| j                                         t	          j        | j        j        |f          }d|_        |                                 | j        	                                sD|
                    d           |                                sn| j        	                                D| j        	                                r|                                  |st          | j                   D ]\  }}	 |
                                 n# t          $ r  w xY wt          |d          rud}|                                r9|dk    r3t!          j        d           |dz  }|                                r|dk    3	 |                                 # t          $ r Y w xY wg | _         | j                            d	           | j        	                                r|                                  |s3|                                  | j                            d
	           dS dS dS )a  
        When ``keep_alive=False``: inserts a poison pill, grabs the exit results, waits until the tasks/results queues
        are done, and waits until all workers are finished.
        When ``keep_alive=True``: inserts a non-lethal poison pill, and waits until the tasks/results queues are done.

        ``join``and ``stop_and_join`` are aliases.

        :param keep_alive: Whether to keep the workers alive
        r\   r   Tr   r   close   r   r   r   FN)r@   rA   insert_non_lethal_poison_pillinsert_poison_pillr8   rb   join_task_queuesr,   rg   r   r   r   r   r   r   r   rn   r   r+  join_results_queues_stop_handler_threads)rK   r2   twidworker_process	try_counts         rL   r   zWorkerPool.stop_and_join  s    = 8	I 8"@@BBBB"55777  (:(KS]R_```AAHGGIII(99;; t$$$zz||  (99;;  !2244 )&&(((  #+4T]+C+C ! !'C&++----%    ~w77 !$%	,5577 +IMM Jt,,,%NI -5577 +IMM!*002222) ! ! ! D!! !#
 22d2CCC !2244 )&&(((  I**,,,"66%6HHHHHq8	I 8	IlI Is    D55E$F99
GGc                 x     j         sdS  j                                        sS j                            t                      j        t                                       dt          d                      j        ' j        	                    t          d                      j
        j        dk    r j         }ng }t          j                    }|                                 t           j
        j                  D ]H}t          j         j        ||f          }|                                 |                    |           I|D ]}|                                                                    j                                         g  _          fdt          t0          t2          fD              _        dS )z
        Tries to do a graceful shutdown of the workers, by interrupting them. In the case processes deadlock it will
        send a sigkill.
        NFzPool was terminatedrs   r8   r*  c                 ,    i | ]}|j         |         S r   )r?   )r   r   rK   s     rL   
<dictcomp>z(WorkerPool.terminate.<locals>.<dictcomp>  s"    ]]]sDK,]]]rN   )r@   rA   r   r   r   r?   ry   r   rI   r%  r;   r1   r8   rG   r{   r_   r+   rb   _terminate_workerrg   appendr   r1  drain_queuesr   r   )rK   threadsdont_wait_eventri   r2  s   `    rL   r   zWorkerPool.terminate  s   
 } 	F !2244 	f66|DDDK%**5NcAdAd*eee %1&44\BW5X5XYYY (K77mGG G'o//O!!!"4#3#:;; " "	$D,B)UdIefff			q!!!!  	 	AFFHHHH 	""$$$ 	''))) ]]]]yR[8\]]]rN   r=  c                    | j         |         | j         |         j        dS |                     |           d}|dk    r	 | j         |                             d           | j         |                                         snjn# t
          $ r Y dS t          $ r Y nw xY w| j                            |           |dz  }|	                                s|
                                 |dk    	 | j         |                                         r>| j         |                                          | j         |                                          n# t
          $ r Y dS t          $ r Y nw xY wt          | j         |         d          r?	 | j         |                                          dS # t
          $ r Y dS t          $ r Y dS w xY wdS )a  
        Terminates a single worker process.

        When a process.join() raises an AssertionError, it means the worker hasn't started yet. In that case, we simply
        return. A ValueError can be raised on Windows systems.

        :param worker_id: Worker ID
        :param dont_wait_event: Event object to indicate whether other termination threads should continue. I.e., when
            we set it to False, threads should wait.
        N
   r   r   r   r   r+  )r@   rp   r   r   r   AssertionErrorr   rA   $drain_results_queue_terminate_workerr   waitr   r   r+  )rK   ri   r=  r5  s       rL   r9  zWorkerPool._terminate_worker  s-    =#+t}Y/G/K/SF 	((333 	!mmi(--c-:::}Y/88:: !      
 CCOTTTNI"))++ '$$&&& !mm&	}Y'0022 0i(22444i(--/// 	 	 	FF 	 	 	D	 4=+W55 	i(..00000!      	 	sJ    A B 
B	BB,AE
 

E#	E#"E#F# #
F=0	F=<F=c                    t           s| j        j        dk    r| j                            |          5  | j                            |          rc| j                            |d           	 t          j        | j	        |         j
        t          j                   n# t          t          f$ r Y nw xY wddd           dS # 1 swxY w Y   dS dS dS )z
        Sends a kill signal to a worker process, but only if we know it's running a task.

        :param worker_id: Worker ID
        r8   FN)r   r;   r1   rA   get_worker_running_task_lockget_worker_running_taskset_worker_running_taskoskillr@   rp   signalSIGUSR1ProcessLookupErrorr   rh   s     rL   r   z&WorkerPool._send_kill_signal_to_workerM  s$     
	4#3#@K#O#O#@@KK 	 	%==iHH &>>y%PPPi 8 <fnMMMM.
;   	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	
	 
	#O#Os5   6B=)/BB=B-*B=,B--B==CCc                    | j                                          | j        R| j                                        r9| j                                         | j                                         d| _        | j        R| j                                        r9| j                                         | j                                         d| _        | j	        9| j	                                        r | j	                                         d| _	        | j
        ;| j
                                        r$| j
                                         d| _
        dS dS dS )zX
        Stops results, restart, timeout, and unexpected death handler threads.
        N)rH   r{   rC   r   rA   #insert_poison_pill_results_listenerr   rD   signal_worker_restart_conditionrE   rF   r   s    rL   r1  z WorkerPool._stop_handler_threadsa  sJ    	(,,... '38T8]8]8_8_3BBDDD(--///+/D( '38T8]8]8_8_3>>@@@(--///+/D( '38T8]8]8_8_3(--///+/D( 1=5>>@@ >16688848D111 >===rN   c                 R    t          | j                                                   dS )z,
        Prints insights per worker
        N)printrJ   r  r   s    rL   print_insightszWorkerPool.print_insights~  s'     	d#7799:::::rN   c                 4    | j                                         S )zt
        Creates insights from the raw insight data

        :return: Dictionary containing worker insights
        )rJ   get_insightsr   s    rL   rS  zWorkerPool.get_insights  s     $11333rN   )Tr   )r6   N)r6   r*   )NNNNNFTNNNNNNN)NNNNNFNNNNNNN)	r   NNNNNNNN)F)4__name__
__module____qualname____doc__r   r	   r   r   r   r   rx   rM   rR   rT   rV   rX   rZ   rj   r`   rc   rd   rf   re   r   r   r   r   r   r   r
   r   r   r   r   r   r   r   r   r  r   r  r   r   r   r   r8   rG   r9  r   r1  rQ  rS  r   rN   rL   r*   r*   !   s	         04D]a'+Edi%9efk).EOm Omx} OmT OmSZ Om!$Om=AOm]aOm"OmGKOm_cOm #'Om >BOm OSOm Om Om Omb2 2 2 2 2 2 29 9 9 9 9 9 9= =T =T = = = =1 1 1 1 1 1 13 34 34 3 3 3 36 6 6 68`s `t ` ` ` `,   @. . . .2# # # #J> > > >@4$ 4 4 4 4   3 4     koptptVZY]jn04KO KO KOE%/4J KOZbcfZg KO&smKO@HKO`hil`mKO%c]KOAEKOimKO "(+KO BJ(ASKO #5/	KO HPPU	KO
 "*%KO
 PXX\]`be]eXfOgKO !)KO :=KO KO KO KO\ ]aRVRW`dcg=AGK:>6= 6=( 6=eE8O>T 6=$,SM6=LTUXM6="*3-6=BJ3-6= (0}6= LP6= $,H#5	6= LTT\K]	6=
 %-UO6=
 RZZ_Q`6= ,4E?6= -5T#s(^,D6= +33-6= DG6= 6= 6= 6=p lpqurvUYae>B15[. [. [.U5(?5K [.[cdg[h [.'}[.AI#[.aijman[.&sm[.BF[.]efn]o[. #8,[. DLE?[. #+5/	[. PXX]	[.
 $,DcN#;[. "*#[. ;DCtO:T[. [. [. [.| ^bSWSXaedh>BHL;?vF vF8 vFuUH_?U vF%-c]vFMUVY]vF#+C=vFCKC=vF )1vF MQvF %-X$6	vF MUU]L^	vF
 &.e_vF
 S[[`RavF -5UOvF .6d38n-EvF ,4C=vF ENcSWY]oD^vF vF vF vFp im[_VZbf#^ #^( #^# #^D #^S[\dSe #^&x0#^FNxFX#^#H-#^DLUO#^ $,E?#^ QYY^P_#^ lo#^ #^ #^ #^J osae\`;?;?	, , , ,$ ,YabjYk ,$,X$6,LTU]L^,!)(!3,JRSX/, *2%, *2%	, EP	, , , ,\   :BI BI BI BI BI BI BIH D+^ +^ +^ +^Z83 8 8UY 8 8 8 8tS T    (9 9 9 9:; ; ; ;4d 4 4 4 4 4 4rN   r*   )AloggingrG  r  rI  r8   rn   typingr   r   r   r   r   r   r	   r
   r   r   numpyr   r   ImportErrormpire.async_resultr   r   r   r   r   mpire.commsr   r   r   r   r   mpire.contextr   r    mpire.dashboard.connection_utilsr   mpire.exceptionr   mpire.insightsr   mpire.paramsr   r   r   r   mpire.progress_barr    mpire.signalr!   mpire.tqdm_utilsr"   r#   mpire.utilsr$   r%   r&   mpire.workerr'   r(   	getLoggerrT  r   r*   r   rN   rL   <module>ri     sw    				        ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `OO   	BOOO` ` ` ` ` ` ` ` ` ` ` ` ` ` T T T T T T T T T T T T T T ? ? ? ? ? ? ? ? M M M M M M . . . . . . ) ) ) ) ) ) Y Y Y Y Y Y Y Y Y Y Y Y 1 1 1 1 1 1 7 7 7 7 7 7 2 2 2 2 2 2 2 2 K K K K K K K K K K 4 4 4 4 4 4 4 4		8	$	$i4 i4 i4 i4 i4 i4 i4 i4 i4 i4s   9 	AA