
    Mpj                         % S r SSKrSSKrSSKJrJrJr  SSKJr  SSK	J
r
Jr   " S S\5      r0 r\\\4   \S'   0 r\\\
4   \S	'   0 r\\\4   \S
'   SS.S jrS rS rS rg)a  Cross-process transport for callback messages.

When a callback is registered on an estimator that uses multiple worker processes, every
worker ends up with its own copy of the callback (sent there by pickling). However, the
user-visible state (e.g. logs being filled in or progress bars advancing) lives on the
main process. This module provides a way for the worker copies to ship their messages
back to the main process over a local endpoint (a UNIX socket on Unix, a Windows named
pipe on Windows).

Remark: we don't use a `multiprocessing.Manager` because its proxy objects become
unusable once the Manager subprocess is gone, e.g. after unpickling in a fresh
interpreter. The only ways to work around that either rely on multiprocessing private
API or give up cross-process capabilities.
    N)Client
ConnectionListener)Thread)Callable
NamedTuplec                   .    \ rS rSr% Sr\\S'   \\S'   Srg)ListenerHandle   aq  A picklable reference to a main-process listener.

Attributes
----------
address : str
    Address of the local endpoint the listener is bound to.
    Workers use this to connect, and the main process also uses it as a key into
    this module's registries to find the live listener.

authkey : bytes
    Shared secret used to authenticate connections to the listener.
addressauthkey N)	__name__
__module____qualname____firstlineno____doc__str__annotations__bytes__static_attributes__r       W/var/www/html/pdf-tiff/venv/lib/python3.13/site-packages/sklearn/callback/_transport.pyr
   r
      s     LNr   r
   
_listeners_message_consumers_worker_connections)ownerc                H  ^ ^^ [         R                  " S5      n[        USS9m[        TR                  US9nT[
        UR                  '   T [        UR                  '   Ub  [        R                  " U[        U5        U 4S jmUU4S jn[        USS9R                  5         U$ )	a  Create a listener for incoming messages on the main process.

Also registers the listener and its message consumer in the module-level dicts.

Parameters
----------
message_consumer : callable
    A one-argument function, `message_consumer(message)`, that processes incoming
    message to update the callback's state. This callable may be called from
    multiple different threads, and must therefore behave in a thread-safe manner.

owner : callback instance, default=None
    Optional owner callback. When provided, the listener is automatically closed
    when `owner` gets garbage-collected.

Returns
-------
listener_handle : ListenerHandle
    A reference to the listener.
       )r   backlog)r   r   c                    >   T" U R                  5       5        U R                  S 5        M)  ! [        [        4 a     g f = f)N)recvsendEOFErrorOSError)connmessage_consumers    r   _handleopen_listener.<locals>._handlei   sB    	 -		$  '" 		s   *- A A c                     >   TR                  5       n [        TU 4SS9R                  5         M-  ! [         a     g f = f)NT)targetargsdaemon)acceptr&   r   start)r'   r)   listeners    r   _acceptopen_listener.<locals>._acceptt   sI    ( '=CCE   s   0 
==T)r,   r.   )osurandomr   r
   r   r   r   weakreffinalizeclose_listenerr   r0   )r(   r   r   listener_handler2   r)   r1   s   `    @@r   open_listenerr:   D   s    * jjnG 5H$X-=-=wOO*2J&&'2B../@	F '$'--/r   c                     [         R                  U R                  S5        [        R                  U R                  S5      nUb  UR	                  5         gg)zEStop listening for `listener_handle` and free its background threads.N)r   popr   r   close)r9   r1   s     r   r8   r8      sC    ?22D9~~o55t<H r   c                     U R                   [        ;   a  g [        U R                   U R                  S9R	                  5         g! [
         a     gf = f)a  Whether the listener at `listener_handle` is usable from this process.

Helper for callbacks that open their listener eagerly (e.g. in `__init__`) and
therefore have to decide, on unpickling, whether to keep the inherited handle
or open a fresh listener. The listener is not reusable when:

- We are the process that originally opened the listener. Reusing the handle
  would route messages through the in-process fast path of `send`, into the
  original instance's message consumer instead of the unpickled instance's.

- The listener is no longer reachable, e.g. unpickling in a fresh interpreter,
  or on a host that cannot reach the original listener.
Fr   T)r   r   r   r   r=   r&   )r9   s    r   can_reuse_listenerr@      sR     *,&&0G0GHNNP   s   ,A 
AAc                    [         R                  U R                  5      nUb	  U" U5        gU R                  n[        R                  U5      nUc  [	        X0R
                  S9nU[        U'   UR                  U5        UR                  5         g)a  Deliver `message` to whoever is listening on `listener_handle`.

There are two possible delivery paths:

- In-process fast path: `send` is called in the same process that called
  `open_listener` for this listener handle. The message consumer can directly be
  called without any serialization overhead.

- Cross-process path: `send` is called in a different process. The worker opens
  a `Client` connection to the main-process listener on first use and caches it
  in `_worker_connections`, so all subsequent messages reuse the same socket.
  `send` then waits for an acknowledgement from the main process so that, by
  the time it returns, the message has actually been processed by the consumer.
Nr?   )r   getr   r   r   r   r$   r#   )r9   messager(   r   
connections        r   r$   r$      s~     *--o.E.EF#!%%G$((1JG-D-DE
'1G$OOGOOr   )r   r4   r6   multiprocessing.connectionr   r   r   	threadingr   typingr   r   r
   r   dictr   r   r   r   r:   r8   r@   r$   r   r   r   <module>rI      s    
  C C  'Z B #%
Dh $*, Dh' ,
 .0 T#z/* / .2 9x.r   