Ë
    >Øïi5„  ã                   óÄ  — 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mZ  ej                  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 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 G d„ dej4                  j6                  «      Z G d„ de«      Zy) a,  Implements `AMQPConnectionWorkflow` - the default workflow of performing
multiple TCP/[SSL]/AMQP connection attempts with timeouts and retries until one
succeeds or all attempts fail.

Defines the interface `AbstractAMQPConnectionWorkflow` that facilitates
implementing custom connection workflows.

é    N)Ú__version__c                   ó   — e Zd ZdZy)ÚAMQPConnectorExceptionzBase exception for this moduleN©Ú__name__Ú
__module__Ú__qualname__Ú__doc__© ó    úa/var/www/html/aiagents/fe/lib/python3.12/site-packages/pika/adapters/utils/connection_workflow.pyr   r      s   „ Ú(r   r   c                   ó   — e Zd ZdZy)ÚAMQPConnectorStackTimeoutz:Overall TCP/[SSL]/AMQP stack connection attempt timed out.Nr   r   r   r   r   r      s   „ ÚDr   r   c                   ó   — e Zd ZdZy)ÚAMQPConnectorAbortedz Asynchronous request was abortedNr   r   r   r   r   r      s   „ Ú*r   r   c                   ó   — e Zd ZdZy)ÚAMQPConnectorWrongStatezjAMQPConnector operation requested in wrong state, such as aborting after
    completion was reported.
    Nr   r   r   r   r   r   "   ó   „ òr   r   c                   ó(   ‡ — e Zd ZdZˆ fd„Zd„ Zˆ xZS )ÚAMQPConnectorPhaseErrorBasezMWrapper for exception that occurred during a particular bring-up phase.

    c                 ó4   •— t        t        | �
  |Ž  || _        y)zÈ

        :param BaseException exception: error that occurred while waiting for a
            subclass-specific protocol bring-up phase to complete.
        :param args: args for parent class
        N)Úsuperr   Ú__init__Ú	exception)Úselfr   ÚargsÚ	__class__s      €r   r   z$AMQPConnectorPhaseErrorBase.__init__-   s   ø€ ô 	Ô)¨4Ñ9¸4Ñ@Ø"ˆ�r   c                 ób   — dj                  | j                  j                  | j                  «      S )Nz{}: {!r})Úformatr   r   r   ©r   s    r   Ú__repr__z$AMQPConnectorPhaseErrorBase.__repr__7   s#   € Ø× Ñ  §¡×!8Ñ!8¸$¿.¹.ÓIÐIr   ©r   r   r	   r
   r   r!   Ú__classcell__©r   s   @r   r   r   (   s   ø„ ñô#öJr   r   c                   ó   — e Zd ZdZy)ÚAMQPConnectorSocketConnectErrorz*Error connecting TCP socket to remote peerNr   r   r   r   r&   r&   ;   s   „ Ú4r   r&   c                   ó   — e Zd ZdZy)Ú AMQPConnectorTransportSetupErrorzOError setting up transport after TCP connected but before AMQP handshake.

    Nr   r   r   r   r(   r(   ?   r   r   r(   c                   ó   — e Zd ZdZy)ÚAMQPConnectorAMQPHandshakeErrorzError during AMQP handshakeNr   r   r   r   r*   r*   E   s   „ Ú%r   r*   c                   ó   — e Zd ZdZy)ÚAMQPConnectionWorkflowAbortedz%AMQP Connection workflow was aborted.Nr   r   r   r   r,   r,   I   s   „ Ú/r   r,   c                   ó   — e Zd ZdZy)Ú AMQPConnectionWorkflowWrongStatezuAMQP Connection Workflow operation requested in wrong state, such as
    aborting after completion was reported.
    Nr   r   r   r   r.   r.   M   r   r   r.   c                   ó(   ‡ — e Zd ZdZˆ fd„Zd„ Zˆ xZS )ÚAMQPConnectionWorkflowFailedz5Indicates that AMQP connection workflow failed.

    c                 óF   •— t        t        | �
  |Ž  t        |«      | _        y)z˜
        :param sequence exceptions: Exceptions that occurred during the
            workflow.
        :param args: args to pass to base class

        N)r   r0   r   ÚtupleÚ
exceptions)r   r3   r   r   s      €r   r   z%AMQPConnectionWorkflowFailed.__init__X   s!   ø€ ô 	Ô*¨DÑ:¸DÑAÜ 
Ó+ˆ�r   c                 óè   — dj                  | j                  j                  t        | j                  «      | j                  d   t        | j                  «      dkD  r| j                  d   «      S d «      S )NzG{}: {} exceptions in all; last exception - {!r}; first exception - {!r}éÿÿÿÿé   r   )r   r   r   Úlenr3   r    s    r   r!   z%AMQPConnectionWorkflowFailed.__repr__b   sk   € ð#ß$*¡FØ—N‘N×+Ñ+¬S°·±Ó-AØ—O‘O BÑ'Ü*-¨d¯o©oÓ*>ÀÒ*B�D—O‘O AÑ&ó%Nð	Nð IMó%Nð	Nr   r"   r$   s   @r   r0   r0   S   s   ø„ ñô,öNr   r0   c                   óp   — e Zd ZdZdZdZdZdZdZdZ	dZ
d	„ Zd
„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zdd„Zy)ÚAMQPConnectorz;Performs a single TCP/[SSL]/AMQP connection workflow.

    r   r6   é   é   é   é   é   c                 ó²   — || _         || _        d| _        d| _        d| _        d| _        d| _        d| _        d| _        d| _	        | j                  | _        y)aª  

        :param callable conn_factory: A function that takes
            `pika.connection.Parameters` as its only arg and returns a brand new
            `pika.connection.Connection`-based adapter instance each time it is
            called. The factory must instantiate the connection with
            `internal_connection_workflow=False`.
        :param pika.adapters.utils.nbio_interface.AbstractIOServices nbio:

        N)Ú_conn_factoryÚ_nbioÚ_addr_recordÚ_conn_paramsÚ_on_doneÚ_tcp_timeout_refÚ_stack_timeout_refÚ	_task_refÚ_sockÚ
_amqp_connÚ_STATE_INITÚ_state)r   Úconn_factoryÚnbios      r   r   zAMQPConnector.__init__w   s^   € ð *ˆÔØˆŒ
Ø ˆÔØ ˆÔØˆŒð !%ˆÔà"&ˆÔàˆŒØˆŒ
ØˆŒà×&Ñ&ˆ�r   c                 ó~  — | j                   | j                  k7  r$t        dj                  | j                   «      «      ‚|| _        || _        || _        | j                  | _         t        j                  | j                  dd Ž | _	        | j                  j                  t        j                  j                  t        j                  d«       t        j                  j!                  | j
                  j"                  | j                  «       | j                  j%                  d«       | j                  d   }t&        j)                  dt*        |«       | j,                  j/                  | j                  || j0                  ¬«      | _        d| _        | j
                  j6                  �?| j,                  j9                  | j
                  j6                  | j:                  «      | _        d| _        | j
                  j>                  �@| j,                  j9                  | j
                  j>                  | j@                  «      | _        yy)	a—  Asynchronously perform a single TCP/[SSL]/AMQP connection attempt.

        :param tuple addr_record: a single resolved address record compatible
            with `socket.getaddrinfo()` format.
        :param pika.connection.Parameters conn_params:
        :param callable on_done: Function to call upon completion of the
            workflow: `on_done(pika.connection.Connection | BaseException)`. If
            exception, it's going to be one of the following:
                `AMQPConnectorSocketConnectError`
                `AMQPConnectorTransportSetupError`
                `AMQPConnectorAMQPHandshakeError`
                `AMQPConnectorAborted`

        ú)Already in progress or finished; state={}Nr;   r6   Fr<   z Pika version %s connecting to %r)Úon_done)!rK   rJ   r   r   rB   rC   rD   Ú
_STATE_TCPÚsocketrH   Ú
setsockoptÚpikaÚcompatÚSOL_TCPÚTCP_NODELAYÚtcp_socket_optsÚset_sock_optsÚtcp_optionsÚsetblockingÚ_LOGÚinfor   rA   Úconnect_socketÚ_on_tcp_connection_donerG   rE   Úsocket_timeoutÚ
call_laterÚ_on_tcp_connection_timeoutrF   Ústack_timeoutÚ_on_overall_timeout)r   Úaddr_recordÚconn_paramsrP   Úaddrs        r   ÚstartzAMQPConnector.start“   sÄ  € ð �;‰;˜$×*Ñ*Ò*Ü)Ø;×BÑBÀ4Ç;Á;ÓOóQð Qð (ˆÔØ'ˆÔØˆŒð —o‘oˆŒÜ—]‘] D×$5Ñ$5°b°qÐ$9Ð:ˆŒ
Ø�
‰
×ÑœdŸk™k×1Ñ1´6×3EÑ3EÀqÔIÜ×Ñ×*Ñ*¨4×+<Ñ+<×+HÑ+HØ+/¯:©:ô	7à�
‰
×Ñ˜uÔ%à× Ñ  Ñ#ˆÜ�	‰	Ð4´kÀ4ÔHØŸ™×2Ñ2Ø�J‰J˜ d×&BÑ&Bð 3ó DˆŒð !%ˆÔØ×Ñ×+Ñ+Ð7Ø$(§J¡J×$9Ñ$9Ø×!Ñ!×0Ñ0Ø×/Ñ/ó%1ˆDÔ!ð
 #'ˆÔØ×Ñ×*Ñ*Ð6Ø&*§j¡j×&;Ñ&;Ø×!Ñ!×/Ñ/°×1IÑ1Ió'KˆDÕ#ð 7r   c                 ó2  — | j                   | j                  k(  rt        d«      ‚| j                   | j                  k(  rt        d«      ‚| j                  | _         | j                  «        t        j                  d| j                  j                  | j                  «       | j                  €Wt        j                  d«       | j                  j                  t        j                   | j"                  t%        «       «      «       y| j                  j&                  s2t        j                  d«       | j                  j)                  dd«       yt        j                  d	«       | j                   | j*                  k(  s J d
j-                  | j                   «      «       ‚y)aš  Abort the workflow asynchronously. The completion callback will be
        called with an instance of AMQPConnectorAborted.

        NOTE: we can't cancel/close synchronously because aborting pika
        Connection and its transport requires an asynchronous operation.

        :raises AMQPConnectorWrongState: If called after completion has been
            reported or the workflow not started yet.
        úCannot abort before starting.ú*Cannot abort after completion was reportedzCAMQPConnector: beginning client-initiated asynchronous abort; %r/%sNzXAMQPConnector.abort(): no connection, so just scheduling completion report via I/O loop.z*AMQPConnector.abort(): closing Connection.é@  z3Client-initiated abort of AMQP Connection Workflow.zCAMQPConnector.abort(): closing of Connection was already initiated.z9Connection is closing, but not in TIMEOUT state; state={})rK   rJ   r   Ú_STATE_DONEÚ_STATE_ABORTINGÚ_deactivater\   r]   rC   ÚhostrB   rI   ÚdebugrA   Úadd_callback_threadsafeÚ	functoolsÚpartialÚ_report_completion_and_cleanupr   Ú
is_closingÚcloseÚ_STATE_TIMEOUTr   r    s    r   ÚabortzAMQPConnector.abortÄ   sI  € ð �;‰;˜$×*Ñ*Ò*Ü)Ð*IÓJÐJà�;‰;˜$×*Ñ*Ò*Ü)Ð*VÓWÐWà×*Ñ*ˆŒØ×ÑÔä�	‰	ðØ ×-Ñ-×2Ñ2°D×4EÑ4Eô	Gð �?‰?Ð"Ü�J‰Jð Dô Eà�J‰J×.Ñ.Ü×!Ñ! $×"EÑ"EÜ"6Ó"8ó:õ;ð —?‘?×-Ò-ô —
‘
ÐGÔHØ—‘×%Ñ%ØÐNõPô
 —
‘
ð 0ô 1à—{‘{ d×&9Ñ&9Ò9ð +ØPß‘f˜TŸ[™[Ó)ó+Ñ9r   c                 óØ   — | j                  «        | j                  �!| j                  j                  «        d| _        d| _        d| _        d| _        d| _        | j                  | _        y)zqCancel asynchronous tasks and clean up to assist garbage collection.

        Transition to STATE_DONE.

        N)	ro   rH   rw   r@   rA   rB   rD   rm   rK   r    s    r   Ú_closezAMQPConnector._closeò   s\   € ð 	×ÑÔà�:‰:Ð!Ø�J‰J×ÑÔØˆDŒJà!ˆÔØˆŒ
Ø ˆÔØˆŒà×&Ñ&ˆ�r   c                 ól  — | j                   � J dj                  | j                  «      «       ‚| j                  �!| j                  j	                  «        d| _        | j
                  �!| j
                  j	                  «        d| _        | j                  �"| j                  j	                  «        d| _        yy)ú$Cancel asynchronous tasks.

        Nz:_deactivate called with self._amqp_conn not None; state={})rI   r   rK   rE   ÚcancelrF   rG   r    s    r   ro   zAMQPConnector._deactivate  s¤   € ð �‰Ð&ð 	ØH×OÑOØ—‘óó	Ð&ð × Ñ Ð,Ø×!Ñ!×(Ñ(Ô*Ø$(ˆDÔ!à×"Ñ"Ð.Ø×#Ñ#×*Ñ*Ô,Ø&*ˆDÔ#à�>‰>Ð%Ø�N‰N×!Ñ!Ô#Ø!ˆD�Nð &r   c                 óÆ   — t        |t        «      rt        j                  d|«       nt        j	                  d|«       | j
                  }| j                  «         ||«       y)z´Clean up and invoke client's `on_done` callback.

        :param pika.connection.Connection | BaseException result: value to pass
            to user's `on_done` callback.
        z%AMQPConnector - reporting failure: %rz%AMQPConnector - reporting success: %rN©Ú
isinstanceÚBaseExceptionr\   Úerrorr]   rD   r{   ©r   ÚresultrP   s      r   ru   z,AMQPConnector._report_completion_and_cleanup  sE   € ô �fœmÔ,Ü�J‰JÐ>ÀÕGä�I‰IÐ=¸vÔFà—-‘-ˆØ�‰Œá��r   c                 óÌ   — d| _         t        t        j                  dj	                  | j
                  j                  | j                  «      «      «      }| j                  |«       y)ztHandle TCP connection timeout

        Reports AMQPConnectorSocketConnectError with socket.timeout inside.

        Nz)TCP connection attempt timed out: {!r}/{})	rE   r&   rR   Útimeoutr   rC   rp   rB   ru   )r   rƒ   s     r   rb   z(AMQPConnector._on_tcp_connection_timeout,  sW   € ð !%ˆÔä/Ü�N‰NÐF×MÑMØ×!Ñ!×&Ñ&¨×(9Ñ(9ó;ó <ó=ˆð 	×+Ñ+¨EÕ2r   c                 óª  — d| _         | j                  }| j                  | _        || j                  k(  rÌdj	                  | j
                  j                  | j                  t        | j
                  j                  «      «      }t        j                  |«       | j                  j                  r J dj	                  | j                  «      «       ‚| j                  j                  s| j                  j                  d|«       y|| j                   k(  rCt#        t%        dj	                  | j
                  j                  | j                  «      «      «      }nq|| j&                  k(  sJ ‚t)        t%        dj	                  | j
                  j                  | j                  t        | j
                  j                  «      «      «      «      }| j+                  |«       y)aË  Handle overall TCP/[SSL]/AMQP connection attempt timeout by reporting
        `Timeout` error to the client.

        Reports AMQPConnectorSocketConnectError if timeout occurred during
            socket TCP connection attempt.
        Reports AMQPConnectorTransportSetupError if timeout occurred during
            tramsport [SSL] setup attempt.
        Reports AMQPConnectorAMQPHandshakeError if timeout occurred during
            AMQP handshake.

        Nz0Timeout while setting up AMQP to {!r}/{}; ssl={}zUnexpected open state of {!r}rl   z*Timeout while connecting socket to {!r}/{}z5Timeout while setting up transport to {!r}/{}; ssl={})rF   rK   rx   Ú_STATE_AMQPr   rC   rp   rB   ÚboolÚssl_optionsr\   rƒ   rI   Úis_openrv   rw   rQ   r&   r   Ú_STATE_TRANSPORTr(   ru   )r   Ú
prev_stateÚmsgrƒ   s       r   rd   z!AMQPConnector._on_overall_timeout9  s„  € ð #'ˆÔà—[‘[ˆ
Ø×)Ñ)ˆŒà˜×)Ñ)Ò)ØE×LÑLØ×!Ñ!×&Ñ&¨×(9Ñ(9Ü�T×&Ñ&×2Ñ2Ó3ó5ˆCô �J‰J�sŒOð —‘×.Ò.ð HØ/×6Ñ6°t·±ÓGóHÐ.à—?‘?×-Ò-Ø—‘×%Ñ% c¨3Ô/Øà˜Ÿ™Ò(Ü3Ü)Ø@×GÑGØ×)Ñ)×.Ñ.°×0AÑ0AóCóDóE‰Eð
  ×!6Ñ!6Ò6Ð6Ð6Ü4Ü)ØKß‘F˜4×,Ñ,×1Ñ1°4×3DÑ3DÜ × 1Ñ 1× =Ñ =Ó>ó@óAóBˆEð 	×+Ñ+¨EÕ2r   c                 óþ  — d| _         | j                  �!| j                  j                  «        d| _        |�<t        j	                  d|| j
                  «       | j                  t        |«      «       yt        j                  d| j                  «       | j                  | _        dx}}| j                  j                  �X| j                  j                  j                  }| j                  j                  j                  }|€| j                  j                   }| j"                  j%                  t'        j(                  | j*                  | j                  «      | j                  ||| j,                  ¬«      | _         d| _	        y)a  Handle completion of asynchronous socket connection attempt.

        Reports AMQPConnectorSocketConnectError if TCP socket connection
            failed.

        :param None|BaseException exc: None on success; exception object on
            failure

        Nz*TCP Connection attempt failed: %r; dest=%rz)TCP connection to broker established: %r.)Úprotocol_factoryÚsockÚssl_contextÚserver_hostnamerP   )rG   rE   r~   r\   rƒ   rB   ru   r&   rq   rH   r�   rK   rC   r‹   Úcontextr”   rp   rA   Úcreate_streaming_connectionrs   rt   r@   Ú _on_transport_establishment_done)r   Úexcr“   r”   s       r   r_   z%AMQPConnector._on_tcp_connection_doneg  sI  € ð ˆŒØ× Ñ Ð,Ø×!Ñ!×(Ñ(Ô*Ø$(ˆDÔ!àˆ?Ü�J‰JÐCÀSØ×(Ñ(ô*à×/Ñ/Ü/°Ó4ô6àô 	�
‰
Ð>ÀÇ
Á
ÔKð ×+Ñ+ˆŒà(,Ð,ˆ�oØ×Ñ×(Ñ(Ð4Ø×+Ñ+×7Ñ7×?Ñ?ˆKØ"×/Ñ/×;Ñ;×KÑKˆOØÐ&Ø"&×"3Ñ"3×"8Ñ"8�àŸ™×?Ñ?Ü&×.Ñ.¨t×/AÑ/AØ/3×/@Ñ/@óBà—‘Ø#Ø+Ø×9Ñ9ð @ó ;ˆŒð ˆ�
r   c           	      ó
  — d| _         t        |t        «      rot        j	                  d|| j
                  j                  | j                  t        | j
                  j                  «      «       | j                  t        |«      «       yt        j                  d|«       |\  }| _        | j                  | _        | j                  j!                  | j"                  d¬«       | j                  j%                  | j"                  «       y)aQ  Handle asynchronous completion of
        `AbstractIOServices.create_streaming_connection()`

        Reports AMQPConnectorTransportSetupError if transport ([SSL]) setup
            failed.

        :param sequence|BaseException result: On success, a two-tuple
            (transport, protocol); on failure, exception instance.

        NzCAttempt to create the streaming transport failed: %r; %r/%s; ssl=%sz"Streaming transport linked up: %r.T)Úremove_default)rG   r�   r‚   r\   rƒ   rC   rp   rB   rŠ   r‹   ru   r(   r]   rI   r‰   rK   Úadd_on_open_error_callbackÚ_on_amqp_handshake_doneÚadd_on_open_callback)r   r…   Ú
_transports      r   r—   z.AMQPConnector._on_transport_establishment_done”  sÕ   € ð ˆŒä�fœmÔ,Ü�J‰Jð Ø!'¨×):Ñ):×)?Ñ)?Ø×!Ñ!¤4¨×(9Ñ(9×(EÑ(EÓ#FôHð ×/Ñ/Ü0°Ó8ô:àô 	�	‰	Ð6¸Ô?Ø&,Ñ#ˆ
�D”Oð ×&Ñ&ˆŒà�‰×2Ñ2Ø×(Ñ(¸ð 	3ô 	?à�‰×,Ñ,¨T×-IÑ-IÕJr   Nc                 óf  — t         j                  d| j                  || j                  j                  | j
                  «       d| _        | j                  | j                  k(  rt        «       }�n3| j                  | j                  k(  rat        t        dj                  | j                  j                  | j
                  t        | j                  j                  «      «      «      «      }n¹| j                  | j                  k(  r}|€9t         j                  d| j                  j                  | j
                  |«       |}net         j                  d| j                  j                  | j
                  |«       t        |«      }n#t         j                  d| j                  ||«       y| j!                  |«       y)aµ  Handle completion of AMQP connection handshake attempt.

        NOTE: we handle two types of callbacks - success with just connection
        arg as well as the open-error callback with connection and error

        Reports AMQPConnectorAMQPHandshakeError if AMQP handshake failed.

        :param pika.connection.Connection connection:
        :param BaseException | None error: None on success, otherwise
            failure

        zJAMQPConnector: AMQP handshake attempt completed; state=%s; error=%r; %r/%sNz,Timeout during AMQP handshake{!r}/{}; ssl={}z8AMQPConnector: AMQP connection established for %r/%s: %rz=AMQPConnector: AMQP connection handshake failed for %r/%s: %rzgAMQPConnector: Ignoring AMQP handshake completion notification due to wrong state=%s; error=%r; conn=%r)r\   rq   rK   rC   rp   rB   rI   rn   r   rx   r*   r   r   rŠ   r‹   r‰   ru   )r   Ú
connectionrƒ   r…   s       r   rœ   z%AMQPConnector._on_amqp_handshake_done¶  sg  € ô 	�
‰
ðØ#Ÿ{™{¨E°4×3DÑ3D×3IÑ3IØ×Ñô	ð ˆŒà�;‰;˜$×.Ñ.Ò.ä)Ó+ŠFØ�[‰[˜D×/Ñ/Ò/Ü4Ü)ØB×IÑIØ×)Ñ)×.Ñ.°×0AÑ0AÜ˜T×.Ñ.×:Ñ:Ó;ó=ó>ó?‰Fð
 �[‰[˜D×,Ñ,Ò,Øˆ}Ü—
‘
ØNØ×%Ñ%×*Ñ*¨D×,=Ñ,=¸zôKð $‘ä—
‘
ð Ø!%×!2Ñ!2×!7Ñ!7¸×9JÑ9JØôô 9¸Ó?‘ô �J‰JðHà—‘˜U Jô0ð à×+Ñ+¨FÕ3r   )N)r   r   r	   r
   rJ   rQ   r�   r‰   rx   rn   rm   r   rh   ry   r{   ro   ru   rb   rd   r_   r—   rœ   r   r   r   r9   r9   j   sk   „ ñð €KØ€JØÐØ€KØ€NØ€OØ€Kò'ò8/Kòb,+ò\'ò&"ò.ò 3ò,3ò\+òZ KôD34r   r9   c                   ó   — e Zd ZdZd„ Zd„ Zy)ÚAbstractAMQPConnectionWorkflowzMInterface for implementing a custom TCP/[SSL]/AMQP connection workflow.

    c                 ó   — t         ‚)a¦  Asynchronously perform the workflow until success or all retries
        are exhausted. Called by the adapter.

        :param sequence connection_configs: A sequence of one or more
            `pika.connection.Parameters`-based objects. Will attempt to connect
            using each config in the given order.
        :param callable connector_factory: call it without args to obtain a new
            instance of `AMQPConnector` for each connection attempt.
            See `AMQPConnector` for details.
        :param native_loop: Native I/O loop passed by app to the adapter or
            obtained by the adapter by default.
        :param callable on_done: Function to call upon completion of the
            workflow:
            `on_done(pika.connection.Connection |
                     AMQPConnectionWorkflowFailed |
                     AMQPConnectionWorkflowAborted)`.
            `Connection`-based adapter on success,
            `AMQPConnectionWorkflowFailed` on failure,
            `AMQPConnectionWorkflowAborted` if workflow was aborted.

        :raises AMQPConnectionWorkflowWrongState: If called in wrong state, such
            as after starting the workflow.
        ©ÚNotImplementedError)r   Úconnection_configsÚconnector_factoryÚnative_looprP   s        r   rh   z$AbstractAMQPConnectionWorkflow.startñ  s
   € ô2 "Ð!r   c                 ó   — t         ‚)a·  Abort the workflow asynchronously. The completion callback will be
        called with an instance of AMQPConnectionWorkflowAborted.

        NOTE: we can't cancel/close synchronously because aborting pika
        Connection and its transport requires an asynchronous operation.

        :raises AMQPConnectionWorkflowWrongState: If called in wrong state, such
            as before starting or after completion has been reported.
        r¤   r    s    r   ry   z$AbstractAMQPConnectionWorkflow.abort  s
   € ô "Ð!r   N)r   r   r	   r
   rh   ry   r   r   r   r¢   r¢   ì  s   „ ñò"ó6
"r   r¢   c                   óš   — e Zd ZdZej
                  Zej                  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d„ Zd„ Zy)ÚAMQPConnectionWorkflowa  Implements Pika's default workflow for performing multiple TCP/[SSL]/AMQP
    connection attempts with timeouts and retries until one succeeds or all
    attempts fail.

    The workflow:
        while not success and retries remain:
            1. For each given config (pika.connection.Parameters object):
                A. Perform DNS resolution of the config's host.
                B. Attempt to establish TCP/[SSL]/AMQP for each resolved address
                   until one succeeds, in which case we're done.
            2. If all configs failed but retries remain, resume from beginning
               after the given retry pause. NOTE: failure of DNS resolution
               is equivalent to one cycle and will be retried after the pause
               if retries remain.

    r   r6   r:   r;   c                 óÎ   — d| _         d| _        || _        d| _        d| _        d| _        d| _        d| _        d| _        d| _	        d| _
        g | _        | j                  | _        y)aã  
        :param int | float retry_pause: Non-negative number of seconds to wait
            before retrying the config sequence. Meaningful only if retries is
            greater than 0. Defaults to 2 seconds.
        :param bool _until_first_amqp_attempt: INTERNAL USE ONLY; ends workflow
            after first AMQP handshake attempt, regardless of outcome (success
            or failure). The automatic connection logic in
            `pika.connection.Connection` enables this because it's not
            designed/tested to reset all state properly to handle more than one
            AMQP handshake attempt.

        TODO: Do we need getaddrinfo timeout?
        TODO: Would it be useful to implement exponential back-off?

        N)Ú_attempts_remainingÚ_retry_pauseÚ_until_first_amqp_attemptrA   Ú_current_config_indexÚ_connection_configsÚ_connector_factoryrD   Ú
_connectorrG   Ú_addrinfo_iterÚ_connection_errorsrJ   rK   )r   r¯   s     r   r   zAMQPConnectionWorkflow.__init__3  ss   € ð  $(ˆÔ Ø ˆÔØ)BˆÔ&ð ˆŒ
ð &*ˆÔ"à#'ˆÔ Ø"&ˆÔØˆŒàˆŒàˆŒØ"ˆÔð #%ˆÔà×&Ñ&ˆ�r   c                 ó   — || _         y)aî  Called by the conneciton adapter only on pika's
        `AMQPConnectionWorkflow` instance to provide it the adapter-specific
        `AbstractIOServices` object before calling the `start()` method.

        NOTE: Custom workflow implementations should use the native I/O loop
        directly because `AbstractIOServices` is private to Pika
        implementation and its interface may change without notice.

        :param pika.adapters.utils.nbio_interface.AbstractIOServices nbio:

        N)rA   )r   rM   s     r   Úset_io_servicesz&AMQPConnectionWorkflow.set_io_services]  s   € ð ˆ�
r   c                 ój  — | j                   | j                  k7  r$t        dj                  | j                   «      «      ‚	 t	        |«       |st        dj                  |«      «      ‚|| _        || _	        || _
        |d   j                  | _        |d   j                  | _        | j                  | _         t         j#                  d«       | j$                  j'                  dt)        j*                  | j,                  d¬	«      «      | _        y# t
        $ r}t        dj                  |«      «      ‚d}~ww xY w)
af  Override `AbstractAMQPConnectionWorkflow.start()`.

        NOTE: This implementation uses `connection_attempts` and `retry_delay`
        values from the last element of the given `connection_configs` sequence
        as the overall number of connection attempts of the entire
        `connection_configs` sequence and pause between each sequence.

        rO   z3connection_configs does not support iteration: {!r}Nz"connection_configs is empty: {!r}.r5   z1Starting AMQP Connection workflow asynchronously.r   T©Úfirst)rK   rJ   r   r   ÚiterÚ	ExceptionÚ	TypeErrorÚ
ValueErrorr±   r²   rD   Úconnection_attemptsr­   Úretry_delayr®   Ú_STATE_ACTIVEr\   rq   rA   ra   rs   rt   Ú_start_new_cycle_asyncrG   )r   r¦   r§   r¨   rP   rƒ   s         r   rh   zAMQPConnectionWorkflow.startk  s"  € ð �;‰;˜$×*Ñ*Ò*Ü)Ø;×BÑBÀ4Ç;Á;ÓOóQð Qð	ÜÐ#Ô$ñ
 "ÜØ4×;Ñ;Ð<NÓOóQð Qð $6ˆÔ Ø"3ˆÔØˆŒà#5°bÑ#9×#MÑ#MˆÔ Ø.¨rÑ2×>Ñ>ˆÔà×(Ñ(ˆŒä�
‰
ÐFÔGð Ÿ™×.Ñ.ØŒy× Ñ  ×!<Ñ!<ÀDÔIóKˆ�øô+ ò 	ÜØE×LÑLØóóð ûð	ús   ¿D
 Ä
	D2ÄD-Ä-D2c                 ó$  — | j                   | j                  k(  rt        d«      ‚| j                   | j                  k(  rt        d«      ‚| j                  | _         | j                  «        t        j                  d«       | j                  €Wt        j                  d«       | j                  j                  t        j                  | j                  t        «       «      «       yt        j                  d«       | j                  j!                  «        y)z<Override `AbstractAMQPConnectionWorkflow.abort()`.

        rj   rk   zFAMQPConnectionWorkflow: beginning client-initiated asynchronous abort.Nz`AMQPConnectionWorkflow.abort(): no connector, so just scheduling completion report via I/O loop.z=AMQPConnectionWorkflow.abort(): requesting connector.abort().)rK   rJ   r   rm   rn   ro   r\   r]   r³   rq   rA   rr   rs   rt   ru   r,   ry   r    s    r   ry   zAMQPConnectionWorkflow.abort—  sâ   € ð �;‰;˜$×*Ñ*Ò*Ü)Ð*IÓJÐJØ�[‰[˜D×,Ñ,Ò,Ü)Ø<ó>ð >ð ×*Ñ*ˆŒØ×ÑÔä�	‰	ð (ô 	)ð �?‰?Ð"Ü�J‰Jð Dô Eà�J‰J×.Ñ.Ü×!Ñ! $×"EÑ"EÜ"?Ó"AóCõDô �J‰Jð ,ô -à�O‰O×!Ñ!Õ#r   c                 ó¨   — | j                  «        d| _        d| _        d| _        d| _        d| _        d| _        d| _        | j                  | _	        y)zrCancel asynchronous tasks and clean up to assist garbage collection.

        Transition to _STATE_DONE.

        N)
ro   r±   rA   r²   rD   r³   r´   rµ   rm   rK   r    s    r   r{   zAMQPConnectionWorkflow._close²  sR   € ð 	×ÑÔà#'ˆÔ ØˆŒ
Ø"&ˆÔØˆŒØˆŒØ"ˆÔØ"&ˆÔà×&Ñ&ˆ�r   c                 ó`   — | j                   �"| j                   j                  «        d| _         yy)r}   N)rG   r~   r    s    r   ro   z"AMQPConnectionWorkflow._deactivateÄ  s*   € ð �>‰>Ð%Ø�N‰N×!Ñ!Ô#Ø!ˆD�Nð &r   c                 óÆ   — t        |t        «      rt        j                  d|«       nt        j	                  d|«       | j
                  }| j                  «         ||«       y)zÃClean up and invoke client's `on_done` callback.

        :param pika.connection.Connection | AMQPConnectionWorkflowFailed result:
            value to pass to user's `on_done` callback.
        z.AMQPConnectionWorkflow - reporting failure: %rz.AMQPConnectionWorkflow - reporting success: %rNr€   r„   s      r   ru   z5AMQPConnectionWorkflow._report_completion_and_cleanupÌ  sE   € ô �fœmÔ,Ü�J‰JÐGÈÕPä�I‰IÐFÈÔOà—-‘-ˆØ�‰Œá��r   c                 óÔ  — d| _         | j                  dk\  sJ | j                  «       ‚| j                  dk  r=t        | j                  «      }t        j                  d|«       | j                  |«       y| xj                  dz  c_        t        j                  d| j                  «       d| _        | j                  j                  |rdn| j                  | j                  «      | _         y)aQ  Start a new workflow cycle (if any more attempts are left) beginning
        with the first Parameters object in self._connection_configs. If out of
        attempts, report `AMQPConnectionWorkflowFailed`.

        :param bool first: if True, don't delay; otherwise delay next attempt by
            `self._retry_pause` seconds.
        Nr   z$AMQP connection workflow failed: %r.r6   zQBeginning a new AMQP connection workflow cycle; attempts remaining after this: %s)rG   r­   r0   rµ   r\   rƒ   ru   rq   r°   rA   ra   r®   Ú_try_next_config_async)r   rº   rƒ   s      r   rÂ   z-AMQPConnectionWorkflow._start_new_cycle_asyncÜ  sÊ   € ð ˆŒà×'Ñ'¨1Ò,ÐF¨d×.FÑ.FÓFÐ,à×#Ñ# qÒ(Ü0°×1HÑ1HÓIˆEÜ�J‰JÐ=¸uÔEØ×/Ñ/°Ô6Øà× Ò  AÑ%Õ Ü�
‰
ð'Ø(,×(@Ñ(@ô	Bð &*ˆÔ"àŸ™×.Ñ.Ù‰A˜D×-Ñ-¨t×/JÑ/JóLˆ�r   c                 óJ  — d| _         | j                  €d| _        n| xj                  dz  c_        | j                  t        | j                  «      k\  r(t        j                  d«       | j                  d¬«       y| j                  | j                     }t        j                  d|j                  |j                  «       | j                   �J ‚| j                  j                  |j                  |j                  | j                  | j                  | j                  ¬«      | _         y)	zwAttempt to connect using the next Parameters config. If there are no
        more configs, start a new cycle.

        Nr   r6   z-_try_next_config_async: starting a new cycle.Fr¹   z_try_next_config_async: %r:%s)rp   ÚportÚsocktypeÚprotorP   )rG   r°   r7   r±   r\   rq   rÂ   rp   rÊ   rA   ÚgetaddrinfoÚ
_SOCK_TYPEÚ_IPPROTOÚ_on_getaddrinfo_async_done)r   Úparamss     r   rÈ   z-AMQPConnectionWorkflow._try_next_config_asyncø  së   € ð
 ˆŒà×%Ñ%Ð-Ø)*ˆDÕ&à×&Ò&¨!Ñ+Õ&à×%Ñ%¬¨T×-EÑ-EÓ)FÒFÜ�J‰JÐFÔGØ×'Ñ'¨eÐ'Ô4Øà×)Ñ)¨$×*DÑ*DÑEˆä�
‰
Ð2°F·K±KÀÇÁÔMð �~‰~Ð%Ð%Ð%ØŸ™×/Ñ/Ø—‘Ø—‘Ø—_‘_Ø—-‘-Ø×3Ñ3ð 0ó 5ˆ�r   c                 ó8  — d| _         t        |t        «      rDt        j	                  d|«       | j
                  j                  |«       | j                  d¬«       yt        j                  dt        |«      «       t        |«      | _        | j                  «        y)zäHandles completion callback from asynchronous `getaddrinfo()`.

        :param list | BaseException addrinfos_or_exc: resolved address records
            returned by `getaddrinfo()` or an exception object from failure.
        Nzgetaddrinfo failed: %r.Fr¹   zgetaddrinfo returned %s records)rG   r�   r‚   r\   rƒ   rµ   ÚappendrÂ   rq   r7   r»   r´   Ú_try_next_resolved_address)r   Úaddrinfos_or_excs     r   rÐ   z1AMQPConnectionWorkflow._on_getaddrinfo_async_done  s~   € ð ˆŒäÐ&¬Ô6Ü�J‰JÐ0Ð2BÔCØ×#Ñ#×*Ñ*Ð+;Ô<Ø×'Ñ'¨eÐ'Ô4Øä�
‰
Ð4´cÐ:JÓ6KÔLÜ"Ð#3Ó4ˆÔà×'Ñ'Õ)r   c                 ól  — 	 t        | j                  «      }t        j	                  d|«       | j                  «       | _        | j                  j                  || j                  | j                     | j                  ¬«       y# t        $ r( t        j	                  d«       | j                  «        Y yw xY w)z}Try connecting using next resolved address. If there aren't any left,
        continue with next Parameters config.

        z8_try_next_resolved_address: continuing with next config.Nz-Attempting to connect using address record %r)re   rf   rP   )Únextr´   ÚStopIterationr\   rq   rÈ   r²   r³   rh   r±   r°   Ú_on_connector_done)r   re   s     r   rÔ   z1AMQPConnectionWorkflow._try_next_resolved_address)  sŸ   € ð
	Ü˜t×2Ñ2Ó3ˆKô 	�
‰
ÐBÀKÔPà×1Ñ1Ó3ˆŒà�‰×ÑØ#Ø×0Ñ0°×1KÑ1KÑLØ×+Ñ+ð 	õ 	-øô ò 	Ü�J‰JØJôLà×'Ñ'Ô)Ùð		ús   ‚B Â.B3Â2B3c                 óº  — d| _         t        j                  d|«       t        |t        «      �r| j
                  j                  |«       t        |t        «      rS| j                  | j                  k(  s J dj                  | j                  «      «       ‚| j                  t        «       «       y| j                  r�t        |t        «      rqt        j                  d«       t        |j                  t         j"                  j$                  «      rt        }nt'        | j
                  «      }| j                  |«       y| j)                  «        y| j                  |«       y)zÌHandle completion of connection attempt by `AMQPConnector`.

        :param pika.connection.Connection | BaseException conn_or_exc: See
            `AMQPConnector.start()` for exception details.

        Nz$Connection attempt completed with %rz&Expected _STATE_ABORTING, but got {!r}zcEnding AMQP connection workflow after first failed AMQP handshake due to _until_first_amqp_attempt.)r³   r\   rq   r�   r‚   rµ   rÓ   r   rK   rn   r   ru   r,   r¯   r*   r   rT   r3   ÚConnectionOpenAbortedr0   rÔ   )r   Úconn_or_excrƒ   s      r   rÙ   z)AMQPConnectionWorkflow._on_connector_done?  s  € ð ˆŒÜ�
‰
Ð9¸;ÔGä�k¤=Õ1Ø×#Ñ#×*Ñ*¨;Ô7ä˜+Ô';Ô<Ø—{‘{ d×&:Ñ&:Ò:ð QØ<×CÑCÀDÇKÁKÓPóQÐ:ð ×3Ñ3Ü1Ó3õ5à×0Ò0Ü˜[Ô*IÔJÜ—
‘
ð Nô Oä˜k×3Ñ3Ü"Ÿo™o×CÑCôEä9‘Eä8Ø×/Ñ/ó1�Eð ×3Ñ3°EÕ:à×/Ñ/Õ1ð ×/Ñ/°Õ<r   N)F)r   r   r	   r
   rR   ÚSOCK_STREAMrÎ   ÚIPPROTO_TCPrÏ   rJ   rÁ   rn   rm   r   r·   rh   ry   r{   ro   ru   rÂ   rÈ   rÐ   rÔ   rÙ   r   r   r   r«   r«     ss   „ ñð" ×#Ñ#€JØ×!Ñ!€Hà€KØ€MØ€OØ€Kó('òTò*KòX$ò6'ò$"òò Lò85ò<*ò&-ó,#=r   r«   )r
   rs   ÚloggingrR   Úpika.compatrT   Úpika.exceptionsÚpika.tcp_socket_optsr   Ú	getLoggerr   r\   r¼   r   r   r   r   r   r&   r(   r*   r,   r.   r0   Úobjectr9   rU   ÚAbstractBaser¢   r«   r   r   r   ú<module>ræ      sü   ðñó Û Û ã Û Û Ý à€w×Ñ˜Ó"€ô)˜Yô )ôEÐ 6ô Eô+Ð1ô +ôÐ4ô ôJÐ"8ô Jô&5Ð&Aô 5ôÐ'Bô ô&Ð&Aô &ô0Ð$:ô 0ôÐ'=ô ôNÐ#9ô Nô.4�Fô 4ôD*" T§[¡[×%=Ñ%=ô *"ôZI=Ð;õ I=r   