Ë
    >Øïi_A  ã                   óX  — d Z 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	Z	ddl
Z	ddlZ	ddlZddlmZ ddlmZ ddlmZmZ ddlmZmZ  ej0                  e«      Z G d„ de«      Z G d	„ d
e«      Z G d„ de«      Z G d„ de«      Z G d„ de«      Z  G d„ de«      Z!y# e$ r ddlZY ŒŒw xY w)z Use pika with the Gevent IOLoop.é    N)ÚBaseConnection)Úcheck_callback_arg)ÚAbstractIOReferenceÚAbstractIOServices)ÚAbstractSelectorIOLoopÚSelectorIOServicesAdapterc                   óF   ‡ — e Zd ZdZ	 	 	 	 	 	 dˆ fd„	Ze	 	 dd„«       Zˆ xZS )ÚGeventConnectionzwImplementation of pika's ``BaseConnection``.

    An async selector-based connection which integrates with Gevent.
    c                 ó   •— t         j                  j                  rt        d«      ‚|xs t	        t        j                  «       «      }t        |t        «      r|}nt        |«      }t        t        | �3  ||||||¬«       y)a  Create a new GeventConnection instance and connect to RabbitMQ on
        Gevent's event-loop.

        :param pika.connection.Parameters|None parameters: The connection
            parameters
        :param callable|None on_open_callback: The method to call when the
            connection is open
        :param callable|None on_open_error_callback: Called if the connection
            can't be established or connection establishment is interrupted by
            `Connection.close()`:
            on_open_error_callback(Connection, exception)
        :param callable|None on_close_callback: Called when a previously fully
            open connection is closed:
            `on_close_callback(Connection, exception)`, where `exception` is
            either an instance of `exceptions.ConnectionClosed` if closed by
            user or broker or exception of another type that describes the
            cause of connection failure
        :param gevent._interfaces.ILoop|nbio_interface.AbstractIOServices|None
            custom_ioloop: Use a custom Gevent ILoop.
        :param bool internal_connection_workflow: True for autonomous connection
            establishment which is default; False for externally-managed
            connection workflow via the `create_connection()` factory
        z-GeventConnection is not supported on Windows.)Úinternal_connection_workflowN)ÚpikaÚcompatÚ
ON_WINDOWSÚRuntimeErrorÚ_GeventSelectorIOLoopÚgeventÚget_hubÚ
isinstancer   Ú _GeventSelectorIOServicesAdapterÚsuperr
   Ú__init__)	ÚselfÚ
parametersÚon_open_callbackÚon_open_error_callbackÚon_close_callbackÚcustom_ioloopr   ÚnbioÚ	__class__s	           €úY/var/www/html/aiagents/fe/lib/python3.12/site-packages/pika/adapters/gevent_connection.pyr   zGeventConnection.__init__'   s   ø€ ô< �;‰;×!Ò!ÜÐNÓOÐOà&ò AÜ.¬v¯~©~Ó/?Ó@ð 	ô �mÔ%7Ô8Ø ‰Dä3°MÓBˆDäÔ Ñ.ØØØ"ØØØ)Eð 	/õ 	Gó    c                 ó–   ‡ ‡— |xs t        t        j                  «       «      }t        |«      Šˆ ˆfd„}‰ j	                  ||‰||¬«      S )z_Implement
        :py:classmethod::`pika.adapters.BaseConnection.create_connection()`.
        c                 ó4   •— | €t        d«      ‚ ‰| ‰d¬«      S )zConnection factory.zIExpected pika.connection.Parameters instance, but got None in params arg.F)r   r   r   )Ú
ValueError)ÚparamsÚclsr   s    €€r    Úconnection_factoryz>GeventConnection.create_connection.<locals>.connection_factoryf   s2   ø€ àˆ~Ü ð "Ió Jð Já &Ø%)Ø49ô;ð ;r!   )Úconnection_configsr'   r   ÚworkflowÚon_done)r   r   r   r   Ú_start_connection_workflow)r&   r(   r*   r   r)   r'   r   s   `     @r    Úcreate_connectionz"GeventConnection.create_connectionX   s\   ù€ ð 'ò AÜ.¬v¯~©~Ó/?Ó@ð 	ô 0°Ó>ˆõ	;ð ×-Ñ-Ø1Ø1ØØØð .ó ð 	r!   )NNNNNT)NN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Úclassmethodr,   Ú__classcell__)r   s   @r    r
   r
   !   s?   ø„ ñð !Ø"&Ø(,Ø#'Ø#Ø.2õ/Gðb ð )-Ø#'ò	ó ôr!   r
   c                   ó2   — e Zd ZdZd„ Zed„ «       Zd„ Zd„ Zy)Ú_TSafeCallbackQueueziDispatch callbacks from any thread to be executed in the main thread
    efficiently with IO events.
    c                 óª   — t        j                  «       | _        t        j                  «       \  | _        | _        t        j                  «       | _	        y)zQ
        :param _GeventSelectorIOLoop loop: IO loop to add callbacks to.
        N)
ÚqueueÚQueueÚ_queueÚosÚpipeÚ_read_fdÚ	_write_fdÚ	threadingÚRLockÚ_write_lock©r   s    r    r   z_TSafeCallbackQueue.__init__|   s6   € ô
 —k‘k“mˆŒä(*¯©«	Ñ%ˆŒ�t”~ô %Ÿ?™?Ó,ˆÕr!   c                 ó   — | j                   S )z?The file-descriptor to register for READ events in the IO loop.)r;   r@   s    r    Úfdz_TSafeCallbackQueue.fdˆ   s   € ð �}‰}Ðr!   c                 ó¼   — | j                   j                  |«       | j                  5  t        j                  | j
                  d«       ddd«       y# 1 sw Y   yxY w)zµAdd an item to the queue from any thread. The configured handler
        will be invoked with the item in the main thread.

        :param item: Object to add to the queue.
        ó   ÿN)r8   Úputr?   r9   Úwriter<   ©r   Úcallbacks     r    Úadd_callback_threadsafez+_TSafeCallbackQueue.add_callback_threadsafe�   sD   € ð 	�‰�‰˜Ô!Ø×Ññ 	.ä�H‰H�T—^‘^ WÔ-÷	.÷ 	.ñ 	.ús   ¨!AÁAc                 óä   — 	 | j                   j                  «       }t        j                  | j                  d«        |«        y# t
        j                  $ r t        j                  d«       Y yw xY w)a  Invoke the next callback from the queue.

        MUST run in the main thread. If no callback was added to the queue,
        this will block the IO loop.

        Performs a blocking READ on the pipe so must only be called when the
        pipe is ready for reading.
        é   zCallback queue was empty.N)	r8   Ú
get_nowaitr9   Úreadr;   r6   ÚEmptyÚLOGGERÚwarningrG   s     r    Úrun_next_callbackz%_TSafeCallbackQueue.run_next_callback˜   sT   € ð	Ø—{‘{×-Ñ-Ó/ˆHô �G‰G�D—M‘M 1Ô%Ù�Jøô �{‰{ò 	8ä�N‰NÐ6Ö7ð	8ús   ‚A Á(A/Á.A/N)	r-   r.   r/   r0   r   ÚpropertyrB   rI   rQ   © r!   r    r4   r4   w   s*   „ ñò
-ð ñó ðò	.ór!   r4   c                   óZ   — e Zd ZdZdZdZdZdd„Zd„ Zd„ Z	d	„ Z
d
„ Zd„ Zd„ Zd„ Zd„ Zd„ Zy)r   z�Implementation of `AbstractSelectorIOLoop` using the Gevent event loop.

    Required by implementations of `SelectorIOServicesAdapter`.
    rK   é   r   Nc                 ó  ‡ — |xs t        j                  «       ‰ _        i ‰ _        t         j                  j                  «       ‰ _        t        «       ‰ _        ˆ fd„}‰ j                  ‰ j                  j                  |‰ j                  «       y)z>
        :param gevent._interfaces.ILoop gevent_loop:
        c                 ó>   •— ~ ~‰j                   j                  «        y)z$Swallow the fd and events arguments.N)Ú_callback_queuerQ   )rB   Úeventsr   s     €r    Úrun_callback_in_main_threadzC_GeventSelectorIOLoop.__init__.<locals>.run_callback_in_main_threadÄ   s   ø€ àØØ× Ñ ×2Ñ2Õ4r!   N)r   r   Ú_hubÚ_io_watchers_by_fdÚhubÚWaiterÚ_waiterr4   rX   Úadd_handlerrB   ÚREAD)r   Ú
gevent_hubrZ   s   `  r    r   z_GeventSelectorIOLoop.__init__¸   sn   ø€ ð Ò2¤&§.¡.Ó"2ˆŒ	Ø"$ˆÔä—z‘z×(Ñ(Ó*ˆŒô  3Ó4ˆÔô	5ð 	×Ñ˜×-Ñ-×0Ñ0Ð2MØŸ™õ	$r!   c                 óZ   — | j                   j                  j                  «        d| _         y)zRelease the loop's resources.N)r[   ÚloopÚdestroyr@   s    r    Úclosez_GeventSelectorIOLoop.closeÍ   s   € à�	‰	�‰×ÑÔ Øˆ�	r!   c                 óÀ   — t         j                  d«       | j                  j                  «        t         j                  d«       | j                  j	                  «        y)zNRun the I/O loop. It will loop until requested to exit. See `stop()`.
        z"Passing control to Gevent's IOLoopz,Control was passed back from Gevent's IOLoopN)rO   Údebugr_   ÚgetÚclearr@   s    r    Ústartz_GeventSelectorIOLoop.startÒ   s>   € ô 	�‰Ð9Ô:Ø�‰×ÑÔä�‰ÐCÔDØ�‰×ÑÕr!   c                 ó:   — | j                   j                  d«       y)a$  Request exit from the ioloop. The loop is NOT guaranteed to
        stop before this method returns.

        To invoke `stop()` safely from a thread other than this IOLoop's thread,
        call it via `add_callback_threadsafe`; e.g.,

            `ioloop.add_callback(ioloop.stop)`
        N)r_   Úswitchr@   s    r    Ústopz_GeventSelectorIOLoop.stopÛ   s   € ð 	�‰×Ñ˜DÕ!r!   c                 ó„  — t        j                  «       | j                  k(  r;t        j	                  d«       | j                  j
                  j                  |«       yt        j	                  d«       t        j                  | j                  j
                  j                  |«      }| j                  j                  |«       y)aù  Requests a call to the given function as soon as possible in the
        context of this IOLoop's thread.

        NOTE: This is the only thread-safe method in IOLoop. All other
        manipulations of IOLoop must be performed from the IOLoop's thread.

        For example, a thread may request a call to the `stop` method of an
        ioloop that is running in a different thread via
        `ioloop.add_callback_threadsafe(ioloop.stop)`

        :param callable callback: The callback method
        z Adding callback from main threadz#Adding callback from another threadN)r   r   r[   rO   rh   rd   Úrun_callbackÚ	functoolsÚpartialrX   rI   rG   s     r    Úadd_callbackz"_GeventSelectorIOLoop.add_callbackæ   s}   € ô �>‰>Ó˜tŸy™yÒ(ä�L‰LÐ;Ô<Ø�I‰I�N‰N×'Ñ'¨Õ1ô
 �L‰LÐ>Ô?Ü ×(Ñ(¨¯©¯©×)DÑ)DÀhÓOˆHØ× Ñ ×8Ñ8¸ÕBr!   c                 ór   — | j                   j                  j                  |«      }|j                  |«       |S )a©  Add the callback to the IOLoop timer to be called after delay seconds
        from the time of call on best-effort basis. Returns a handle to the
        timeout.

        :param float delay: The number of seconds to wait to call callback
        :param callable callback: The callback method
        :returns: handle to the created timeout that may be passed to
            `remove_timeout()`
        :rtype: object
        )r[   rd   Útimerrk   )r   ÚdelayrH   ru   s       r    Ú
call_laterz _GeventSelectorIOLoop.call_laterÿ   s-   € ð —	‘	—‘×$Ñ$ UÓ+ˆØ�‰�HÔØˆr!   c                 ó$   — |j                  «        y)zURemove a timeout

        :param timeout_handle: Handle of timeout to remove
        N)rf   )r   Útimeout_handles     r    Úremove_timeoutz$_GeventSelectorIOLoop.remove_timeout  s   € ð
 	×ÑÕr!   c                 ó”   — | j                   j                  j                  ||«      }|| j                  |<   |j	                  |||«       y)a  Start watching the given file descriptor for events

        :param int fd: The file descriptor
        :param callable handler: When requested event(s) occur,
            `handler(fd, events)` will be called.
        :param int events: The event mask (READ|WRITE)
        N)r[   rd   Úior\   rk   )r   rB   ÚhandlerrY   Ú
io_watchers        r    r`   z!_GeventSelectorIOLoop.add_handler  s@   € ð —Y‘Y—^‘^×&Ñ& r¨6Ó2ˆ
Ø&0ˆ×Ñ Ñ#Ø×Ñ˜ " fÕ-r!   c                 óš   — | j                   |   }|j                  }|j                  «        | j                   |= | j                  |||«       y)z”Change the events being watched for.

        :param int fd: The file descriptor
        :param int events: The new event mask (READ|WRITE)
        N)r\   rH   rf   r`   )r   rB   rY   r~   rH   s        r    Úupdate_handlerz$_GeventSelectorIOLoop.update_handler!  sM   € ð ×,Ñ,¨RÑ0ˆ
ð ×&Ñ&ˆØ×ÑÔØ×#Ñ# BÐ'Ø×Ñ˜˜X vÕ.r!   c                 ó\   — | j                   |   }|j                  «        | j                   |= y)zgStop watching the given file descriptor for events

        :param int fd: The file descriptor
        N)r\   rf   )r   rB   r~   s      r    Úremove_handlerz$_GeventSelectorIOLoop.remove_handler/  s.   € ð
 ×,Ñ,¨RÑ0ˆ
Ø×ÑÔØ×#Ñ# BÑ'r!   )N)r-   r.   r/   r0   ra   ÚWRITEÚERRORr   rf   rk   rn   rs   rw   rz   r`   r€   r‚   rS   r!   r    r   r   ¬   sK   „ ñð €DØ€EØ€Eó$ò*ò
ò	"òCò2òò
.ò/ó(r!   r   c                   ó    — e Zd ZdZ	 	 	 	 dd„Zy)r   zESelectorIOServicesAdapter implementation using Gevent's DNS resolver.c           
      ór   — t        | j                  |||||||¬«      }|j                  «        t        |«      S )zOImplement :py:meth:`.nbio_interface.AbstractIOServices.getaddrinfo()`.
        )Únative_loopÚhostÚportÚfamilyÚsocktypeÚprotoÚflagsr*   )Ú_GeventAddressResolverÚ_looprk   Ú_GeventIOLoopIOHandle)	r   rˆ   r‰   r*   rŠ   r‹   rŒ   r�   Úresolvers	            r    Úgetaddrinfoz,_GeventSelectorIOServicesAdapter.getaddrinfo<  s@   € ô *°d·j±jØ/3Ø/3Ø17Ø3;Ø05Ø05Ø29ô;ˆð 	�‰Ôä$ XÓ.Ð.r!   N)r   r   r   r   )r-   r.   r/   r0   r’   rS   r!   r    r   r   9  s   „ ÙOð ØØØô/r!   r   c                   ó   — e Zd ZdZd„ Zd„ Zy)r�   zXImplement `AbstractIOReference`.

    Only used to wrap the _GeventAddressResolver.
    c                 ó&   — |j                   | _        y)zY
        :param subject: subject of the reference containing a `cancel()` method
        N)ÚcancelÚ_cancel)r   Úsubjects     r    r   z_GeventIOLoopIOHandle.__init__Y  s   € ð —~‘~ˆ�r!   c                 ó"   — | j                  «       S )z€Cancel pending operation

        :returns: False if was already done or cancelled; True otherwise
        :rtype: bool
        )r–   r@   s    r    r•   z_GeventIOLoopIOHandle.cancel_  s   € ð �|‰|‹~Ðr!   N)r-   r.   r/   r0   r   r•   rS   r!   r    r�   r�   S  s   „ ñò
&ór!   r�   c                   ó>   — e Zd ZdZdZd„ Zd„ Zd„ Zd„ Zd„ Z	d„ Z
d	„ Zy
)rŽ   z½Performs getaddrinfo asynchronously Gevent's configured resolver in a
    separate greenlet and invoking the provided callback with the result.

    See: http://www.gevent.org/dns.html
    )	r�   Ú_on_doneÚ	_greenletÚ_ga_hostÚ_ga_portÚ
_ga_familyÚ_ga_socktypeÚ	_ga_protoÚ	_ga_flagsc	                 óš   — t        |d«       || _        || _        d| _        || _        || _        || _        || _        || _        || _	        y)a²  Initialize the `_GeventAddressResolver`.

        :param AbstractSelectorIOLoop native_loop:
        :param host: `see socket.getaddrinfo()`
        :param port: `see socket.getaddrinfo()`
        :param family: `see socket.getaddrinfo()`
        :param socktype: `see socket.getaddrinfo()`
        :param proto: `see socket.getaddrinfo()`
        :param flags: `see socket.getaddrinfo()`
        :param on_done: on_done(records|BaseException) callback for reporting
            result from the given I/O loop. The single arg will be either an
            exception object (check for `BaseException`) in case of failure or
            the result returned by `socket.getaddrinfo()`.
        r*   N)
r   r�   rš   r›   rœ   r�   rž   rŸ   r    r¡   )	r   r‡   rˆ   r‰   rŠ   r‹   rŒ   r�   r*   s	            r    r   z_GeventAddressResolver.__init__z  sN   € ô  	˜7 IÔ.à ˆŒ
ØˆŒàˆŒàˆŒØˆŒØ ˆŒØ$ˆÔØˆŒØˆ�r!   c                 ó�   — | j                   €%t        j                  | j                  «      | _         yt        j                  d«       y)z-Start an asynchronous getaddrinfo invocation.Nz&_GeventAddressResolver already started)r›   r   Ú	spawn_rawÚ_resolverO   rP   r@   s    r    rk   z_GeventAddressResolver.start˜  s/   € à�>‰>Ð!Ü#×-Ñ-¨d¯m©mÓ<ˆD�Nä�N‰NÐCÕDr!   c                 óf   — d}| j                   �d}| j                  «        | j                  «        |S )zCancel the pending resolver.FT)r›   Ú_stop_greenletÚ_cleanup)r   Úchangeds     r    r•   z_GeventAddressResolver.cancelŸ  s0   € àˆà�>‰>Ð%ØˆGØ×ÑÔ!à�‰ŒØˆr!   c                 ó@   — | j                  «        d| _        d| _        y)z,Stop the resolver and release any resources.N)r§   r�   rš   r@   s    r    r¨   z_GeventAddressResolver._cleanupª  s   € à×ÑÔØˆŒ
Øˆ�r!   c                 ój   — | j                   �'t        j                  | j                   «       d| _         yy)zbStop the greenlet performing getaddrinfo if running.

        Otherwise, this is a no-op.
        N)r›   r   Úkillr@   s    r    r§   z%_GeventAddressResolver._stop_greenlet°  s*   € ð
 �>‰>Ð%Ü�K‰K˜Ÿ™Ô'Ø!ˆD�Nð &r!   c                 ó˜  — 	 t         j                  j                  | j                  | j                  | j
                  | j                  | j                  | j                  «      }t        j                  | j                  |«      }| j                  j!                  |«       y# t        $ r"}t        j                  d|«       |}Y d}~Œbd}~ww xY w)zoCall `getaddrinfo()` and return result via user's callback
        function on the configured IO loop.
        zAddress resolution failed: %rN)r   Úsocketr’   rœ   r�   rž   rŸ   r    r¡   Ú	ExceptionrO   Úerrorrq   rr   Ú_dispatch_callbackr�   rs   )r   ÚresultÚexcrH   s       r    r¥   z_GeventAddressResolver._resolve¹  s—   € ð	ä—]‘]×.Ñ.¨t¯}©}¸d¿m¹mØ/3¯©Ø/3×/@Ñ/@Ø/3¯~©~¸t¿~¹~óOˆFô ×$Ñ$ T×%<Ñ%<¸fÓEˆØ�
‰
×Ñ Õ)øô ò 	Ü�L‰LÐ8¸#Ô>Ø�Fûð	ús   ‚A B Â	C	Â'CÃC	c                 ó²   — 	 t         j                  d| j                  «       | j                  |«       | j	                  «        y# | j	                  «        w xY w)z›Invoke the configured completion callback and any subsequent cleanup.

        :param result: result from getaddrinfo, or the exception if raised.
        z9Invoking async getaddrinfo() completion callback; host=%rN)rO   rh   rœ   rš   r¨   )r   r²   s     r    r±   z)_GeventAddressResolver._dispatch_callbackÊ  s>   € ð
	Ü�L‰LØKØ—‘ôð �M‰M˜&Ô!à�M‰M�OøˆD�M‰M�Oús   ‚1A ÁAN)r-   r.   r/   r0   Ú	__slots__r   rk   r•   r¨   r§   r¥   r±   rS   r!   r    rŽ   rŽ   h  s2   „ ñð

€Iòò<Eò	òò"ò*ó"r!   rŽ   )"r0   rq   Úloggingr9   r=   Úweakrefr6   ÚImportErrorr7   r   Ú
gevent.hubÚgevent.socketÚpika.compatr   Úpika.adapters.base_connectionr   Ú%pika.adapters.utils.io_services_utilsr   Ú"pika.adapters.utils.nbio_interfacer   r   Ú+pika.adapters.utils.selector_ioloop_adapterr   r   Ú	getLoggerr-   rO   r
   Úobjectr4   r   r   r�   rŽ   rS   r!   r    ú<module>rÂ      sº   ðÙ &ã Û Û 	Û Û ðÛó Û Û ã Ý 8Ý D÷÷ð
 
ˆ×	Ñ	˜8Ó	$€ôS�~ô Sôl2˜&ô 2ôjJ(Ð2ô J(ôZ/Ð'@ô /ô4Ð/ô ô*m˜Võ møð{
 ò Ýðús   ˜B Â	B)Â(B)