
    0Fie                        d Z ddlmZ ddlZddlZddlZddlZddlZddlm	Z
 ddlmZ  ej        e          Z ej                    Zd Z G d de
j                  Zdd
Zd Z ej                    ZdS )a  
Modified ThreadPoolExecutor to support threads leaving the thread pool

This includes a global `secede` method that a submitted function can call to
have its thread leave the ThreadPoolExecutor's thread pool.  This allows the
thread pool to allocate another thread if necessary and so is useful when a
function realises that it is going to be a long-running job that doesn't want
to take up space.  When the function finishes its thread will terminate
gracefully.

This code copies and modifies two functions from the
`concurrent.futures.thread` module, notably `_worker` and
ThreadPoolExecutor._adjust_thread_count` to allow for checking against a global
`threading.local` state.  These functions are subject to the following license,
which is included as a comment at the end of this file:

    https://docs.python.org/3/license.html

... and are under copyright by the Python Software Foundation

   Copyright 2001-2016 Python Software Foundation; All Rights Reserved
    )annotationsN)_concurrent_futures_thread)timec                \   dt           _        | t           _        	 t           j        r6| j        5  | j        r| j                                        \  }}| j                            |           | j                            t          j
                               |                                 	 d d d            n	 d d d            n# 1 swxY w Y   	 |                    d          }n# t          j        $ r Y w xY w||                                 ~n;t           j        s	| | j        r&|                    d            	 t           `t           `d S t           j        6~ n,# t&          $ r t(                              dd           Y nw xY wt           `t           `d S # t           `t           `w xY w)NT   timeoutzException in worker)exc_info)thread_stateproceedexecutor_rejoin_lock_rejoin_listpop_threadsaddremove	threadingcurrent_threadsetgetqueueEmptyrunthread	_shutdownputBaseExceptionloggercritical)r   
work_queuerejoin_threadrejoin_eventtasks        >lib/python3.11/site-packages/distributed/threadpoolexecutor.py_workerr&   '   s(   L$L"" 	&  ( 2:2G2K2K2M2M/M<%))-888%,,Y-E-G-GHHH $$&&&                    !~~a~00;   


D! X%59K%5t$$$
  !!!/ " 	$ H > > >-=====>  !!!  !!!!!s~   E A>C,E 9E C		E C	E C( 'E (C:7E 9C::AE E F &FF FF F+c                  J     e Zd Z ej                    Z fdZd ZddZ xZ	S )ThreadPoolExecutorc                     t                      j        |i | g | _        t          j                    | _        |                    dd          | _        d S )Nthread_name_prefixDaskThreadPoolExecutor)super__init__r   r   Lockr   r   _thread_name_prefix)selfargskwargs	__class__s      r%   r-   zThreadPoolExecutor.__init__J   sY    $)&)))%N,,#):: ":$
 $
       c           	     T   t          | j                  | j        k     rt          j        t
          | j        dt          j                    t          | j
                  fz  z   | | j        f          }d|_        | j                            |           |                                 d S d S )Nz-%d-%d)targetnamer1   T)lenr   _max_workersr   Threadr&   r/   osgetpidnext_counter_work_queuedaemonr   start)r0   ts     r%   _adjust_thread_countz'ThreadPoolExecutor._adjust_thread_countR   s    t} 111 -bikk4+>+>??@D,-	  A AHMa   GGIIIII 21r4   TNc                x   t           5  | j        5  d| _        | j                            d            d d d            n# 1 swxY w Y   |t                      |z   }|rD| j        D ]<}| t          |t                      z
  d          }nd }|                    |           =d d d            d S # 1 swxY w Y   d S )NTr   r   )	threads_lock_shutdown_lockr   r?   r   r   r   maxjoin)r0   waitr	   deadlinerB   timeout2s         r%   shutdownzThreadPoolExecutor.shutdown^   sS    	- 	-$ + +!% $$T***+ + + + + + + + + + + + + + + "66G+ - - -A*#&x$&&'8!#<#<#'FF8F,,,,	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	-s2   B/">B/A	B/A	AB//B36B3)TN)
__name__
__module____qualname__	itertoolscountr>   r-   rC   rL   __classcell__)r3   s   @r%   r(   r(   F   sj        y  H
 
 
 
 

 
 
- - - - - - - -r4   r(   Tc                   dt           _        t          5  t           j        j                            t          j                               | rt           j                                         ddd           dS # 1 swxY w Y   dS )zwHave this thread secede from the ThreadPoolExecutor

    See Also
    --------
    rejoin : rejoin the thread pool
    FN)	r   r   rE   r   r   r   r   r   rC   )adjusts    r%   secederU   n   s     !L	 9 9&--i.F.H.HIII 	9!668889 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9s   AA77A;>A;c                 L   t          j                    } t          j                    }t          j        }|j        5  |j                            | |f           ddd           n# 1 swxY w Y   |                    d            |	                                 dt          _
        dS )a  Have this thread rejoin the ThreadPoolExecutor

    This will block until a new slot opens up in the executor.  The next thread
    to finish a task will leave the pool to allow this one to join.

    See Also
    --------
    secede : leave the thread pool
    Nc                     d S )N rX   r4   r%   <lambda>zrejoin.<locals>.<lambda>   s    T r4   T)r   r   Eventr   r   r   r   appendsubmitrI   r   )r   eventes      r%   rejoinr_   |   s     %''FOEA	
 / /	vuo.../ / / / / / / / / / / / / / /HH\\	JJLLLLs   A##A'*A')T)__doc__
__future__r   rP   loggingr;   r   r   distributedr   r   distributed.metricsr   	getLoggerrM   r   localr   r&   r(   rU   r_   r.   rE   rX   r4   r%   <module>rg      s   , # " " " " "      				      < < < < < < $ $ $ $ $ $		8	$	$y  " " ">%- %- %- %- %-2 %- %- %-P9 9 9 9     ( y~- -r4   