§
    øžyj¥	  ã                  ó`   — d Z ddlmZ ddlZddlZddlmZ ddlmZ dgZ	 G d„ de¦  «        Z
dS )uÎ  Shared daemon-thread ThreadPoolExecutor.

Stdlib ``ThreadPoolExecutor`` workers are non-daemon AND are registered in
``concurrent.futures.thread._threads_queues``, whose atexit hook
(``_python_exit``) joins every worker unconditionally â€” even after
``shutdown(wait=False)``.  A single wedged worker (tool blocked on network
I/O, hung provider daemon, stuck subagent) therefore blocks interpreter
exit forever.  This is the root cause of multi-minute CLI exits on long
sessions: every abandoned concurrent-tool batch leaves workers that the
exit hook insists on joining.

``DaemonThreadPoolExecutor`` spawns daemon workers and skips the
``_threads_queues`` registration, so:

  - ``_python_exit`` never joins them, and
  - the interpreter's non-daemon thread join at shutdown skips them.

Semantics are otherwise identical (initializer/initargs, work queue,
idle-thread reuse).  Use it for any pool whose work is best-effort or
independently interruptible and must never hold the process open:
concurrent tool execution, background memory sync, catalog fan-out,
subagent timeout wrappers.  Do NOT use it for work that must complete
before exit (durable writes) â€” those belong on foreground threads with
explicit bounded joins.
é    )ÚannotationsN)ÚThreadPoolExecutor)Ú_workerÚDaemonThreadPoolExecutorc                  ó   — e Zd ZdZdd„ZdS )r   zCThreadPoolExecutor variant whose workers do not block process exit.ÚreturnÚNonec                ó”  — | j                              d¬¦  «        rd S | j        fd„}t          | j        ¦  «        }|| j        k     r�d| j        p| |fz  }t          j        |t          t          j        | |¦  «        | j        | j        | j        fd¬¦  «        }|                     ¦   «          | j                             |¦  «         d S d S )Nr   )Útimeoutc                ó0   — |                      d ¦  «         d S )N)Úput)Ú_Úqs     ú7/home/ragecks/.hermes/hermes-agent/tools/daemon_pool.pyÚ
weakref_cbzADaemonThreadPoolExecutor._adjust_thread_count.<locals>.weakref_cb.   s   € Ø�EŠE�$‰KŒKˆKˆKˆKó    z%s_%dT)ÚnameÚtargetÚargsÚdaemon)Ú_idle_semaphoreÚacquireÚ_work_queueÚlenÚ_threadsÚ_max_workersÚ_thread_name_prefixÚ	threadingÚThreadr   ÚweakrefÚrefÚ_initializerÚ	_initargsÚstartÚadd)Úselfr   Únum_threadsÚthread_nameÚts        r   Ú_adjust_thread_countz-DaemonThreadPoolExecutor._adjust_thread_count(   sï   € ð Ô×'Ò'°Ð'Ñ2Ô2ð 	ØˆFà Ô,ð 	ð 	ð 	ð 	õ ˜$œ-Ñ(Ô(ˆØ˜Ô*Ò*Ð*Ø! TÔ%=Ð%EÀÀ{Ð$SÑSˆKÝÔ Ø Ýå”K  jÑ1Ô1ØÔ$ØÔ%Ø”Nð	ð ð
ñ 
ô 
ˆAð �GŠG‰IŒIˆIØŒM×Ò˜aÑ Ô Ð Ð Ð ð +Ð*r   N)r   r	   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r*   © r   r   r   r   %   s.   € € € € € ØMÐMð!ð !ð !ð !ð !ð !r   )r.   Ú
__future__r   r   r    Úconcurrent.futuresr   Úconcurrent.futures.threadr   Ú__all__r   r/   r   r   ú<module>r4      s™   ððð ð4 #Ð "Ð "Ð "Ð "Ð "à Ð Ð Ð Ø €€€Ø 1Ð 1Ð 1Ð 1Ð 1Ð 1Ø -Ð -Ð -Ð -Ð -Ð -à%Ð
&€ð!ð !ð !ð !ð !Ð1ñ !ô !ð !ð !ð !r   