o
    h{                     @  sZ  d Z ddlmZ ddlZddlmZmZ ddlmZm	Z	m
Z
mZmZ ddlmZ ddlmZmZ ddlmZmZ dd	lmZmZ erTdd
lmZ ddlmZ ddlmZ eddZeg g g g g ZG dd dZG dd deZ G dd deZ!G dd deZ"G dd deZ#G dd deZ$dudd Z%dvd%d&Z&dwd)d*Z'dxd/d0Z(G d1d2 d2Z)G d3d4 d4e)Z*G d5d6 d6e)Z+G d7d8 d8e)Z,G d9d: d:Z-G d;d< d<e-Z.G d=d> d>e-Z/G d?d@ d@e-Z0G dAdB dBe-Z1G dCdD dDZ2G dEdF dFZ3G dGdH dHZ4G dIdJ dJe4Z5G dKdL dLe5Z6G dMdN dNe5Z7G dOdP dPe6Z8G dQdR dRe5Z9G dSdT dTe4Z:G dUdV dVe6Z;G dWdX dXe6Z<G dYdZ dZe5Z=G d[d\ d\Z>G d]d^ d^e>Z?G d_d` d`e>Z@G dadb dbe>ZAG dcdd ddZBG dedf dfeBZCG dgdh dheBZDG didj djeBZEG dkdl dlZFG dmdn dneFZGG dodp dpeFZHG dqdr dreFZIG dsdt dtZJdS )ya  Tools to monitor driver events.

.. versionadded:: 3.1

.. attention:: Starting in PyMongo 3.11, the monitoring classes outlined below
    are included in the PyMongo distribution under the
    :mod:`~pymongo.event_loggers` submodule.

.. seealso:: This module is compatible with both the synchronous and asynchronous PyMongo APIs.


Use :func:`register` to register global listeners for specific events.
Listeners must inherit from one of the abstract classes below and implement
the correct functions for that class.

For example, a simple command logger might be implemented like this::

    import logging

    from pymongo import monitoring

    class CommandLogger(monitoring.CommandListener):

        def started(self, event):
            logging.info("Command {0.command_name} with request id "
                         "{0.request_id} started on server "
                         "{0.connection_id}".format(event))

        def succeeded(self, event):
            logging.info("Command {0.command_name} with request id "
                         "{0.request_id} on server {0.connection_id} "
                         "succeeded in {0.duration_micros} "
                         "microseconds".format(event))

        def failed(self, event):
            logging.info("Command {0.command_name} with request id "
                         "{0.request_id} on server {0.connection_id} "
                         "failed in {0.duration_micros} "
                         "microseconds".format(event))

    monitoring.register(CommandLogger())

Server discovery and monitoring events are also available. For example::

    class ServerLogger(monitoring.ServerListener):

        def opened(self, event):
            logging.info("Server {0.server_address} added to topology "
                         "{0.topology_id}".format(event))

        def description_changed(self, event):
            previous_server_type = event.previous_description.server_type
            new_server_type = event.new_description.server_type
            if new_server_type != previous_server_type:
                # server_type_name was added in PyMongo 3.4
                logging.info(
                    "Server {0.server_address} changed type from "
                    "{0.previous_description.server_type_name} to "
                    "{0.new_description.server_type_name}".format(event))

        def closed(self, event):
            logging.warning("Server {0.server_address} removed from topology "
                            "{0.topology_id}".format(event))


    class HeartbeatLogger(monitoring.ServerHeartbeatListener):

        def started(self, event):
            logging.info("Heartbeat sent to server "
                         "{0.connection_id}".format(event))

        def succeeded(self, event):
            # The reply.document attribute was added in PyMongo 3.4.
            logging.info("Heartbeat to server {0.connection_id} "
                         "succeeded with reply "
                         "{0.reply.document}".format(event))

        def failed(self, event):
            logging.warning("Heartbeat to server {0.connection_id} "
                            "failed with error {0.reply}".format(event))

    class TopologyLogger(monitoring.TopologyListener):

        def opened(self, event):
            logging.info("Topology with id {0.topology_id} "
                         "opened".format(event))

        def description_changed(self, event):
            logging.info("Topology description updated for "
                         "topology id {0.topology_id}".format(event))
            previous_topology_type = event.previous_description.topology_type
            new_topology_type = event.new_description.topology_type
            if new_topology_type != previous_topology_type:
                # topology_type_name was added in PyMongo 3.4
                logging.info(
                    "Topology {0.topology_id} changed type from "
                    "{0.previous_description.topology_type_name} to "
                    "{0.new_description.topology_type_name}".format(event))
            # The has_writable_server and has_readable_server methods
            # were added in PyMongo 3.4.
            if not event.new_description.has_writable_server():
                logging.warning("No writable servers available.")
            if not event.new_description.has_readable_server():
                logging.warning("No readable servers available.")

        def closed(self, event):
            logging.info("Topology with id {0.topology_id} "
                         "closed".format(event))

Connection monitoring and pooling events are also available. For example::

    class ConnectionPoolLogger(ConnectionPoolListener):

        def pool_created(self, event):
            logging.info("[pool {0.address}] pool created".format(event))

        def pool_ready(self, event):
            logging.info("[pool {0.address}] pool is ready".format(event))

        def pool_cleared(self, event):
            logging.info("[pool {0.address}] pool cleared".format(event))

        def pool_closed(self, event):
            logging.info("[pool {0.address}] pool closed".format(event))

        def connection_created(self, event):
            logging.info("[pool {0.address}][connection #{0.connection_id}] "
                         "connection created".format(event))

        def connection_ready(self, event):
            logging.info("[pool {0.address}][connection #{0.connection_id}] "
                         "connection setup succeeded".format(event))

        def connection_closed(self, event):
            logging.info("[pool {0.address}][connection #{0.connection_id}] "
                         "connection closed, reason: "
                         "{0.reason}".format(event))

        def connection_check_out_started(self, event):
            logging.info("[pool {0.address}] connection check out "
                         "started".format(event))

        def connection_check_out_failed(self, event):
            logging.info("[pool {0.address}] connection check out "
                         "failed, reason: {0.reason}".format(event))

        def connection_checked_out(self, event):
            logging.info("[pool {0.address}][connection #{0.connection_id}] "
                         "connection checked out of pool".format(event))

        def connection_checked_in(self, event):
            logging.info("[pool {0.address}][connection #{0.connection_id}] "
                         "connection checked into pool".format(event))


Event listeners can also be registered per instance of
:class:`~pymongo.mongo_client.MongoClient`::

    client = MongoClient(event_listeners=[CommandLogger()])

Note that previously registered global listeners are automatically included
when configuring per client event listeners. Registering a new global listener
will not add that listener to existing client instances.

.. note:: Events are delivered **synchronously**. Application threads block
  waiting for event handlers (e.g. :meth:`~CommandListener.started`) to
  return. Care must be taken to ensure that your event handlers are efficient
  enough to not adversely affect overall application performance.

.. warning:: The command documents published through this API are *not* copies.
  If you intend to modify them in any way you must copy them in your event
  handler first.
    )annotationsN)abc
namedtuple)TYPE_CHECKINGAnyMappingOptionalSequence)ObjectId)HelloHelloCompat)_SENSITIVE_COMMANDS_handle_exception)_Address_DocumentOut)	timedelta)ServerDescription)TopologyDescription
_Listeners)command_listenersserver_listenersserver_heartbeat_listenerstopology_listenerscmap_listenersc                   @  s   e Zd ZdZdS )_EventListenerz,Abstract base class for all event listeners.N)__name__
__module____qualname____doc__ r   r   E/var/www/html/venv/lib/python3.10/site-packages/pymongo/monitoring.pyr      s    r   c                   @  .   e Zd ZdZdddZdd	d
ZdddZdS )CommandListenerzAbstract base class for command listeners.

    Handles `CommandStartedEvent`, `CommandSucceededEvent`,
    and `CommandFailedEvent`.
    eventCommandStartedEventreturnNonec                 C     t )zAbstract method to handle a `CommandStartedEvent`.

        :param event: An instance of :class:`CommandStartedEvent`.
        NotImplementedErrorselfr#   r   r   r    started      zCommandListener.startedCommandSucceededEventc                 C  r'   )zAbstract method to handle a `CommandSucceededEvent`.

        :param event: An instance of :class:`CommandSucceededEvent`.
        r(   r*   r   r   r    	succeeded   r-   zCommandListener.succeededCommandFailedEventc                 C  r'   )z}Abstract method to handle a `CommandFailedEvent`.

        :param event: An instance of :class:`CommandFailedEvent`.
        r(   r*   r   r   r    failed   r-   zCommandListener.failedN)r#   r$   r%   r&   )r#   r.   r%   r&   )r#   r0   r%   r&   r   r   r   r   r,   r/   r1   r   r   r   r    r"      s
    

r"   c                   @  s~   e Zd ZdZd'ddZd(d	d
Zd)ddZd*ddZd+ddZd,ddZ	d-ddZ
d.ddZd/ddZd0d!d"Zd1d$d%Zd&S )2ConnectionPoolListenera-  Abstract base class for connection pool listeners.

    Handles all of the connection pool events defined in the Connection
    Monitoring and Pooling Specification:
    :class:`PoolCreatedEvent`, :class:`PoolClearedEvent`,
    :class:`PoolClosedEvent`, :class:`ConnectionCreatedEvent`,
    :class:`ConnectionReadyEvent`, :class:`ConnectionClosedEvent`,
    :class:`ConnectionCheckOutStartedEvent`,
    :class:`ConnectionCheckOutFailedEvent`,
    :class:`ConnectionCheckedOutEvent`,
    and :class:`ConnectionCheckedInEvent`.

    .. versionadded:: 3.9
    r#   PoolCreatedEventr%   r&   c                 C  r'   )zAbstract method to handle a :class:`PoolCreatedEvent`.

        Emitted when a connection Pool is created.

        :param event: An instance of :class:`PoolCreatedEvent`.
        r(   r*   r   r   r    pool_created     z#ConnectionPoolListener.pool_createdPoolReadyEventc                 C  r'   )zAbstract method to handle a :class:`PoolReadyEvent`.

        Emitted when a connection Pool is marked ready.

        :param event: An instance of :class:`PoolReadyEvent`.

        .. versionadded:: 4.0
        r(   r*   r   r   r    
pool_ready  s   	z!ConnectionPoolListener.pool_readyPoolClearedEventc                 C  r'   )zAbstract method to handle a `PoolClearedEvent`.

        Emitted when a connection Pool is cleared.

        :param event: An instance of :class:`PoolClearedEvent`.
        r(   r*   r   r   r    pool_cleared"  r6   z#ConnectionPoolListener.pool_clearedPoolClosedEventc                 C  r'   )zAbstract method to handle a `PoolClosedEvent`.

        Emitted when a connection Pool is closed.

        :param event: An instance of :class:`PoolClosedEvent`.
        r(   r*   r   r   r    pool_closed+  r6   z"ConnectionPoolListener.pool_closedConnectionCreatedEventc                 C  r'   )zAbstract method to handle a :class:`ConnectionCreatedEvent`.

        Emitted when a connection Pool creates a Connection object.

        :param event: An instance of :class:`ConnectionCreatedEvent`.
        r(   r*   r   r   r    connection_created4  r6   z)ConnectionPoolListener.connection_createdConnectionReadyEventc                 C  r'   )zAbstract method to handle a :class:`ConnectionReadyEvent`.

        Emitted when a connection has finished its setup, and is now ready to
        use.

        :param event: An instance of :class:`ConnectionReadyEvent`.
        r(   r*   r   r   r    connection_ready=     z'ConnectionPoolListener.connection_readyConnectionClosedEventc                 C  r'   )zAbstract method to handle a :class:`ConnectionClosedEvent`.

        Emitted when a connection Pool closes a connection.

        :param event: An instance of :class:`ConnectionClosedEvent`.
        r(   r*   r   r   r    connection_closedG  r6   z(ConnectionPoolListener.connection_closedConnectionCheckOutStartedEventc                 C  r'   )zAbstract method to handle a :class:`ConnectionCheckOutStartedEvent`.

        Emitted when the driver starts attempting to check out a connection.

        :param event: An instance of :class:`ConnectionCheckOutStartedEvent`.
        r(   r*   r   r   r    connection_check_out_startedP  r6   z3ConnectionPoolListener.connection_check_out_startedConnectionCheckOutFailedEventc                 C  r'   )zAbstract method to handle a :class:`ConnectionCheckOutFailedEvent`.

        Emitted when the driver's attempt to check out a connection fails.

        :param event: An instance of :class:`ConnectionCheckOutFailedEvent`.
        r(   r*   r   r   r    connection_check_out_failedY  r6   z2ConnectionPoolListener.connection_check_out_failedConnectionCheckedOutEventc                 C  r'   )zAbstract method to handle a :class:`ConnectionCheckedOutEvent`.

        Emitted when the driver successfully checks out a connection.

        :param event: An instance of :class:`ConnectionCheckedOutEvent`.
        r(   r*   r   r   r    connection_checked_outb  r6   z-ConnectionPoolListener.connection_checked_outConnectionCheckedInEventc                 C  r'   )zAbstract method to handle a :class:`ConnectionCheckedInEvent`.

        Emitted when the driver checks in a connection back to the connection
        Pool.

        :param event: An instance of :class:`ConnectionCheckedInEvent`.
        r(   r*   r   r   r    connection_checked_ink  rA   z,ConnectionPoolListener.connection_checked_inN)r#   r4   r%   r&   )r#   r7   r%   r&   )r#   r9   r%   r&   )r#   r;   r%   r&   )r#   r=   r%   r&   )r#   r?   r%   r&   )r#   rB   r%   r&   )r#   rD   r%   r&   )r#   rF   r%   r&   )r#   rH   r%   r&   )r#   rJ   r%   r&   )r   r   r   r   r5   r8   r:   r<   r>   r@   rC   rE   rG   rI   rK   r   r   r   r    r3      s    

	

	
	
	


	
	
		r3   c                   @  r!   )ServerHeartbeatListenerzAbstract base class for server heartbeat listeners.

    Handles `ServerHeartbeatStartedEvent`, `ServerHeartbeatSucceededEvent`,
    and `ServerHeartbeatFailedEvent`.

    .. versionadded:: 3.3
    r#   ServerHeartbeatStartedEventr%   r&   c                 C  r'   )zAbstract method to handle a `ServerHeartbeatStartedEvent`.

        :param event: An instance of :class:`ServerHeartbeatStartedEvent`.
        r(   r*   r   r   r    r,     r-   zServerHeartbeatListener.startedServerHeartbeatSucceededEventc                 C  r'   )zAbstract method to handle a `ServerHeartbeatSucceededEvent`.

        :param event: An instance of :class:`ServerHeartbeatSucceededEvent`.
        r(   r*   r   r   r    r/     r-   z!ServerHeartbeatListener.succeededServerHeartbeatFailedEventc                 C  r'   )zAbstract method to handle a `ServerHeartbeatFailedEvent`.

        :param event: An instance of :class:`ServerHeartbeatFailedEvent`.
        r(   r*   r   r   r    r1     r-   zServerHeartbeatListener.failedN)r#   rM   r%   r&   )r#   rN   r%   r&   )r#   rO   r%   r&   r2   r   r   r   r    rL   v  s
    

rL   c                   @  r!   )TopologyListenerzAbstract base class for topology monitoring listeners.
    Handles `TopologyOpenedEvent`, `TopologyDescriptionChangedEvent`, and
    `TopologyClosedEvent`.

    .. versionadded:: 3.3
    r#   TopologyOpenedEventr%   r&   c                 C  r'   )zAbstract method to handle a `TopologyOpenedEvent`.

        :param event: An instance of :class:`TopologyOpenedEvent`.
        r(   r*   r   r   r    opened  r-   zTopologyListener.openedTopologyDescriptionChangedEventc                 C  r'   )zAbstract method to handle a `TopologyDescriptionChangedEvent`.

        :param event: An instance of :class:`TopologyDescriptionChangedEvent`.
        r(   r*   r   r   r    description_changed  r-   z$TopologyListener.description_changedTopologyClosedEventc                 C  r'   )zAbstract method to handle a `TopologyClosedEvent`.

        :param event: An instance of :class:`TopologyClosedEvent`.
        r(   r*   r   r   r    closed  r-   zTopologyListener.closedN)r#   rQ   r%   r&   )r#   rS   r%   r&   )r#   rU   r%   r&   r   r   r   r   rR   rT   rV   r   r   r   r    rP     
    

rP   c                   @  r!   )ServerListenerzAbstract base class for server listeners.
    Handles `ServerOpeningEvent`, `ServerDescriptionChangedEvent`, and
    `ServerClosedEvent`.

    .. versionadded:: 3.3
    r#   ServerOpeningEventr%   r&   c                 C  r'   )z}Abstract method to handle a `ServerOpeningEvent`.

        :param event: An instance of :class:`ServerOpeningEvent`.
        r(   r*   r   r   r    rR     r-   zServerListener.openedServerDescriptionChangedEventc                 C  r'   )zAbstract method to handle a `ServerDescriptionChangedEvent`.

        :param event: An instance of :class:`ServerDescriptionChangedEvent`.
        r(   r*   r   r   r    rT     r-   z"ServerListener.description_changedServerClosedEventc                 C  r'   )z{Abstract method to handle a `ServerClosedEvent`.

        :param event: An instance of :class:`ServerClosedEvent`.
        r(   r*   r   r   r    rV     r-   zServerListener.closedN)r#   rZ   r%   r&   )r#   r[   r%   r&   )r#   r\   r%   r&   rW   r   r   r   r    rY     rX   rY   durr   r%   intc                 C  s   t |  d S )z'Convert duration 'dur' to microseconds.g    .A)r^   total_seconds)r]   r   r   r    
_to_micros  s   r`   optionstr	listenersSequence[_EventListeners]c                 C  sR   t |tjst|  dt| |D ]}t |ts&td|  dt| q|S )zValidate event listenersz must be a list or tuple, not Listeners for | must be either a CommandListener, ServerHeartbeatListener, ServerListener, TopologyListener, or ConnectionPoolListener,not )
isinstancer   r	   	TypeErrortyper   )ra   rc   listenerr   r   r    _validate_event_listeners  s   
rk   rj   r&   c                 C  s   t | tstd|  dt|  t | trtj|  t | tr'tj	|  t | t
r2tj|  t | tr=tj|  t | trJtj|  dS dS )zRegister a global event listener.

    :param listener: A subclasses of :class:`CommandListener`,
        :class:`ServerHeartbeatListener`, :class:`ServerListener`,
        :class:`TopologyListener`, or :class:`ConnectionPoolListener`.
    re   rf   N)rg   r   rh   ri   r"   
_LISTENERSr   appendrL   r   rY   r   rP   r   r3   r   )rj   r   r   r    register  s"   





rn   command_namedocMapping[str, Any]boolc                 C  s"   |   dtjfv rd|v rdS dS )NZhelloZspeculativeAuthenticateTF)lowerr   Z
LEGACY_CMD)ro   rp   r   r   r    _is_speculative_authenticate  s   rt   c                   @  s   e Zd ZdZdZ			d#d$ddZed%ddZed&ddZed'ddZ	ed(ddZ
ed)ddZed%dd Zed)d!d"ZdS )*_CommandEventzBase class for command events.)Z
__cmd_nameZ	__rqst_idZ	__conn_idZ__op_id__service_idZ__dbZ__server_conn_idN ro   rb   
request_idr^   connection_idr   operation_idOptional[int]
service_idOptional[ObjectId]database_nameserver_connection_idr%   r&   c                 C  s.   || _ || _|| _|| _|| _|| _|| _d S N)_CommandEvent__cmd_name_CommandEvent__rqst_id_CommandEvent__conn_id_CommandEvent__op_id_CommandEvent__service_id_CommandEvent__db_CommandEvent__server_conn_id)r+   ro   rx   ry   rz   r|   r~   r   r   r   r    __init__  s   

z_CommandEvent.__init__c                 C     | j S )zThe command name.)r   r+   r   r   r    ro   -     z_CommandEvent.command_namec                 C  r   )z"The request id for this operation.)r   r   r   r   r    rx   2  r   z_CommandEvent.request_idc                 C  r   )z@The address (host, port) of the server this command was sent to.)r   r   r   r   r    ry   7  r   z_CommandEvent.connection_idc                 C  r   )z^The service_id this command was sent to, or ``None``.

        .. versionadded:: 3.12
        )r   r   r   r   r    r|   <     z_CommandEvent.service_idc                 C  r   )z(An id for this series of events or None.)r   r   r   r   r    rz   D  r   z_CommandEvent.operation_idc                 C  r   )z^The database_name this command was sent to, or ``""``.

        .. versionadded:: 4.6
        )r   r   r   r   r    r~   I  r   z_CommandEvent.database_namec                 C  r   )zThe server-side connection id for the connection this command was sent on, or ``None``.

        .. versionadded:: 4.7
        )r   r   r   r   r    r   Q  r   z"_CommandEvent.server_connection_idNrw   N)ro   rb   rx   r^   ry   r   rz   r{   r|   r}   r~   rb   r   r{   r%   r&   r%   rb   r%   r^   r%   r   r%   r}   )r%   r{   )r   r   r   r   	__slots__r   propertyro   rx   ry   r|   rz   r~   r   r   r   r   r    ru     s*    ru   c                      sV   e Zd ZdZdZ		dd fddZedddZed fddZdddZ	  Z
S )r$   a  Event published when a command starts.

    :param command: The command document.
    :param database_name: The name of the database this command was run against.
    :param request_id: The request id for this operation.
    :param connection_id: The address (host, port) of the server this command
        was sent to.
    :param operation_id: An optional identifier for a series of related events.
    :param service_id: The service_id this command was sent to, or ``None``.
    )Z__cmdNcommandr   r~   rb   rx   r^   ry   r   rz   r{   r|   r}   r   r%   r&   c           
   	     sf   |s	t |dtt|}t j|||||||d | }	|	tv s)t|	|r.i | _d S || _d S )Nz is not a valid commandr|   r~   r   )	
ValueErrornextitersuperr   rs   r   rt   _CommandStartedEvent__cmd)
r+   r   r~   rx   ry   rz   r|   r   ro   cmd_name	__class__r   r    r   h  s    
	

zCommandStartedEvent.__init__c                 C  r   )zThe command document.)r   r   r   r   r    r     r   zCommandStartedEvent.commandc                      t  jS )z6The name of the database this command was run against.)r   r~   r   r   r   r    r~     s   z!CommandStartedEvent.database_namec              	   C  s&   d | jj| j| j| j| j| j| jS )Nz[<{} {} db: {!r}, command: {!r}, operation_id: {}, service_id: {}, server_connection_id: {}>)	formatr   r   ry   r~   ro   rz   r|   r   r   r   r   r    __repr__  s   zCommandStartedEvent.__repr__NN)r   r   r~   rb   rx   r^   ry   r   rz   r{   r|   r}   r   r{   r%   r&   r%   r   r   )r   r   r   r   r   r   r   r   r~   r   __classcell__r   r   r   r    r$   Z  s    	r$   c                      T   e Zd ZdZdZ			dd  fddZed!ddZed"ddZd#ddZ	  Z
S )$r.   aO  Event published when a command succeeds.

    :param duration: The command duration as a datetime.timedelta.
    :param reply: The server reply document.
    :param command_name: The command name.
    :param request_id: The request id for this operation.
    :param connection_id: The address (host, port) of the server this command
        was sent to.
    :param operation_id: An optional identifier for a series of related events.
    :param service_id: The service_id this command was sent to, or ``None``.
    :param database_name: The database this command was sent to, or ``""``.
    )__duration_micros__replyNrw   durationdatetime.timedeltareplyr   ro   rb   rx   r^   ry   r   rz   r{   r|   r}   r~   r   r%   r&   c
              	     sR   t  j|||||||	d t|| _| }
|
tv st|
|r$i | _d S || _d S Nr   )r   r   r`   '_CommandSucceededEvent__duration_microsrs   r   rt   _CommandSucceededEvent__reply)r+   r   r   ro   rx   ry   rz   r|   r~   r   r   r   r   r    r     s   
	

zCommandSucceededEvent.__init__c                 C  r   z/The duration of this operation in microseconds.)r   r   r   r   r    duration_micros  r   z%CommandSucceededEvent.duration_microsc                 C  r   z/The server failure document for this operation.)r   r   r   r   r    r     r   zCommandSucceededEvent.replyc              
   C  s*   d | jj| j| j| j| j| j| j| j	S )Nzp<{} {} db: {!r}, command: {!r}, operation_id: {}, duration_micros: {}, service_id: {}, server_connection_id: {}>)
r   r   r   ry   r~   ro   rz   r   r|   r   r   r   r   r    r     s   zCommandSucceededEvent.__repr__r   )r   r   r   r   ro   rb   rx   r^   ry   r   rz   r{   r|   r}   r~   rb   r   r{   r%   r&   r   r   r   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r.     s    
r.   c                      r   )$r0   aN  Event published when a command fails.

    :param duration: The command duration as a datetime.timedelta.
    :param failure: The server reply document.
    :param command_name: The command name.
    :param request_id: The request id for this operation.
    :param connection_id: The address (host, port) of the server this command
        was sent to.
    :param operation_id: An optional identifier for a series of related events.
    :param service_id: The service_id this command was sent to, or ``None``.
    :param database_name: The database this command was sent to, or ``""``.
    )r   Z	__failureNrw   r   r   failurer   ro   rb   rx   r^   ry   r   rz   r{   r|   r}   r~   r   r%   r&   c
           
   	     s.   t  j|||||||	d t|| _|| _d S r   )r   r   r`   $_CommandFailedEvent__duration_micros_CommandFailedEvent__failure)
r+   r   r   ro   rx   ry   rz   r|   r~   r   r   r   r    r     s   
	
zCommandFailedEvent.__init__c                 C  r   r   )r   r   r   r   r    r   
  r   z"CommandFailedEvent.duration_microsc                 C  r   r   )r   r   r   r   r    r     r   zCommandFailedEvent.failurec                 C  s.   d | jj| j| j| j| j| j| j| j	| j
	S )Nz<{} {} db: {!r}, command: {!r}, operation_id: {}, duration_micros: {}, failure: {!r}, service_id: {}, server_connection_id: {}>)r   r   r   ry   r~   ro   rz   r   r   r|   r   r   r   r   r    r     s   zCommandFailedEvent.__repr__r   )r   r   r   r   ro   rb   rx   r^   ry   r   rz   r{   r|   r}   r~   rb   r   r{   r%   r&   r   r   r   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r0     s    
r0   c                   @  6   e Zd ZdZdZdddZedd	d
ZdddZdS )
_PoolEventzBase class for pool events.Z	__addressaddressr   r%   r&   c                 C  
   || _ d S r   _PoolEvent__addressr+   r   r   r   r    r   *     
z_PoolEvent.__init__c                 C  r   )zbThe address (host, port) pair of the server the pool is attempting
        to connect to.
        r   r   r   r   r    r   -     z_PoolEvent.addressrb   c                 C     | j j d| jdS N())r   r   r   r   r   r   r    r   4     z_PoolEvent.__repr__Nr   r   r%   r&   r   r   	r   r   r   r   r   r   r   r   r   r   r   r   r    r   %      
r   c                      >   e Zd ZdZdZd fd	d
ZedddZdddZ  Z	S )r4   zPublished when a Connection Pool is created.

    :param address: The address (host, port) pair of the server this Pool is
       attempting to connect to.

    .. versionadded:: 3.9
    )Z	__optionsr   r   optionsdict[str, Any]r%   r&   c                      t  | || _d S r   )r   r   _PoolCreatedEvent__options)r+   r   r   r   r   r    r   C     
zPoolCreatedEvent.__init__c                 C  r   )zCAny non-default pool options that were set on this Connection Pool.)r   r   r   r   r    r   G  r   zPoolCreatedEvent.optionsrb   c                 C     | j j d| jd| jdS Nr   z, r   )r   r   r   r   r   r   r   r    r   L     zPoolCreatedEvent.__repr__r   r   r   r   r%   r&   )r%   r   r   )
r   r   r   r   r   r   r   r   r   r   r   r   r   r    r4   8  s    r4   c                   @     e Zd ZdZdZdS )r7   zPublished when a Connection Pool is marked ready.

    :param address: The address (host, port) pair of the server this Pool is
       attempting to connect to.

    .. versionadded:: 4.0
    r   Nr   r   r   r   r   r   r   r   r    r7   P      r7   c                      sR   e Zd ZdZdZ		dd fddZedddZedddZdddZ	  Z
S )r9   aw  Published when a Connection Pool is cleared.

    :param address: The address (host, port) pair of the server this Pool is
       attempting to connect to.
    :param service_id: The service_id this command was sent to, or ``None``.
    :param interrupt_connections: True if all active connections were interrupted by the Pool during clearing.

    .. versionadded:: 3.9
    )rv   Z__interrupt_connectionsNFr   r   r|   r}   interrupt_connectionsrr   r%   r&   c                   s   t  | || _|| _d S r   )r   r   _PoolClearedEvent__service_id(_PoolClearedEvent__interrupt_connections)r+   r   r|   r   r   r   r    r   i     
zPoolClearedEvent.__init__c                 C  r   )zConnections with this service_id are cleared.

        When service_id is ``None``, all connections in the pool are cleared.

        .. versionadded:: 3.12
        )r   r   r   r   r    r|   s  s   zPoolClearedEvent.service_idc                 C  r   )zdIf True, active connections are interrupted during clearing.

        .. versionadded:: 4.7
        )r   r   r   r   r    r   }  r   z&PoolClearedEvent.interrupt_connectionsrb   c                 C  &   | j j d| jd| jd| jdS r   )r   r   r   r   r   r   r   r   r    r        &zPoolClearedEvent.__repr__)NFr   r   r|   r}   r   rr   r%   r&   r   r%   rr   r   )r   r   r   r   r   r   r   r|   r   r   r   r   r   r   r    r9   \  s    

	r9   c                   @  r   )r;   zPublished when a Connection Pool is closed.

    :param address: The address (host, port) pair of the server this Pool is
       attempting to connect to.

    .. versionadded:: 3.9
    r   Nr   r   r   r   r    r;     r   r;   c                   @  s&   e Zd ZdZdZ	 dZ	 dZ	 dZdS )ConnectionClosedReasonzqAn enum that defines values for `reason` on a
    :class:`ConnectionClosedEvent`.

    .. versionadded:: 3.9
    staleZidleerror
poolClosedN)r   r   r   r   ZSTALEZIDLEERRORPOOL_CLOSEDr   r   r   r    r     s    r   c                   @  s    e Zd ZdZdZ	 dZ	 dZdS )ConnectionCheckOutFailedReasonzyAn enum that defines values for `reason` on a
    :class:`ConnectionCheckOutFailedEvent`.

    .. versionadded:: 3.9
    timeoutr   ZconnectionErrorN)r   r   r   r   TIMEOUTr   Z
CONN_ERRORr   r   r   r    r     s    r   c                   @  r   )_ConnectionEventz)Private base class for connection events.r   r   r   r%   r&   c                 C  r   r   _ConnectionEvent__addressr   r   r   r    r     r   z_ConnectionEvent.__init__c                 C  r   )ziThe address (host, port) pair of the server this connection is
        attempting to connect to.
        r   r   r   r   r    r     r   z_ConnectionEvent.addressrb   c                 C  r   r   )r   r   r   r   r   r   r    r     r   z_ConnectionEvent.__repr__Nr   r   r   r   r   r   r   r    r     r   r   c                      r   )_ConnectionIdEventz4Private base class for connection events with an id.)__connection_idr   r   ry   r^   r%   r&   c                   r   r   )r   r   !_ConnectionIdEvent__connection_id)r+   r   ry   r   r   r    r     r   z_ConnectionIdEvent.__init__c                 C  r   )zThe ID of the connection.)r   r   r   r   r    ry     r   z _ConnectionIdEvent.connection_idrb   c                 C  r   r   )r   r   r   r   r   r   r   r    r     r   z_ConnectionIdEvent.__repr__r   r   ry   r^   r%   r&   r   r   )
r   r   r   r   r   r   r   ry   r   r   r   r   r   r    r     s    r   c                      s>   e Zd ZdZdZd fddZedddZdddZ  Z	S )_ConnectionDurationEventz9Private base class for connection events with a duration.)
__durationr   r   ry   r^   r   Optional[float]r%   r&   c                      t  || || _d S r   )r   r   "_ConnectionDurationEvent__duration)r+   r   ry   r   r   r   r    r        
z!_ConnectionDurationEvent.__init__c                 C  r   )zMThe duration of the connection event.

        .. versionadded:: 4.7
        )r   r   r   r   r    r     r   z!_ConnectionDurationEvent.durationrb   c                 C  r   r   )r   r   r   ry   r   r   r   r   r    r     r   z!_ConnectionDurationEvent.__repr__)r   r   ry   r^   r   r   r%   r&   )r%   r   r   )
r   r   r   r   r   r   r   r   r   r   r   r   r   r    r     s    r   c                   @  r   )r=   a  Published when a Connection Pool creates a Connection object.

    NOTE: This connection is not ready for use until the
    :class:`ConnectionReadyEvent` is published.

    :param address: The address (host, port) pair of the server this
       Connection is attempting to connect to.
    :param connection_id: The integer ID of the Connection in this Pool.

    .. versionadded:: 3.9
    r   Nr   r   r   r   r    r=     s    r=   c                   @  r   )r?   a&  Published when a Connection has finished its setup, and is ready to use.

    :param address: The address (host, port) pair of the server this
       Connection is attempting to connect to.
    :param connection_id: The integer ID of the Connection in this Pool.

    .. versionadded:: 3.9
    r   Nr   r   r   r   r    r?         	r?   c                      s>   e Zd ZdZdZd fd	d
ZedddZdddZ  Z	S )rB   aK  Published when a Connection is closed.

    :param address: The address (host, port) pair of the server this
       Connection is attempting to connect to.
    :param connection_id: The integer ID of the Connection in this Pool.
    :param reason: A reason explaining why this connection was closed.

    .. versionadded:: 3.9
    Z__reasonr   r   ry   r^   reasonrb   c                   r   r   )r   r   _ConnectionClosedEvent__reason)r+   r   ry   r   r   r   r    r   !  r   zConnectionClosedEvent.__init__r%   c                 C  r   )zA reason explaining why this connection was closed.

        The reason must be one of the strings from the
        :class:`ConnectionClosedReason` enum.
        )r   r   r   r   r    r   %     zConnectionClosedEvent.reasonc                 C     d | jj| j| j| jS )Nz{}({!r}, {!r}, {!r}))r   r   r   r   ry   r   r   r   r   r    r   .     zConnectionClosedEvent.__repr__)r   r   ry   r^   r   rb   r   
r   r   r   r   r   r   r   r   r   r   r   r   r   r    rB     s    
rB   c                   @  r   )rD   zPublished when the driver starts attempting to check out a connection.

    :param address: The address (host, port) pair of the server this
       Connection is attempting to connect to.

    .. versionadded:: 3.9
    r   Nr   r   r   r   r    rD   7  r   rD   c                      s>   e Zd ZdZdZd fddZedddZdddZ  Z	S )rF   a!  Published when the driver's attempt to check out a connection fails.

    :param address: The address (host, port) pair of the server this
       Connection is attempting to connect to.
    :param reason: A reason explaining why connection check out failed.

    .. versionadded:: 3.9
    r   r   r   r   rb   r   r   r%   r&   c                   s   t  j|d|d || _d S )Nr   )r   ry   r   )r   r   &_ConnectionCheckOutFailedEvent__reason)r+   r   r   r   r   r   r    r   O  s   
z&ConnectionCheckOutFailedEvent.__init__c                 C  r   )zA reason explaining why connection check out failed.

        The reason must be one of the strings from the
        :class:`ConnectionCheckOutFailedReason` enum.
        )r   r   r   r   r    r   S  r   z$ConnectionCheckOutFailedEvent.reasonc                 C  r   r   )r   r   r   r   r   r   r   r   r    r   \  r   z&ConnectionCheckOutFailedEvent.__repr__)r   r   r   rb   r   r   r%   r&   r   r   r   r   r   r    rF   C  s    	rF   c                   @  r   )rH   a  Published when the driver successfully checks out a connection.

    :param address: The address (host, port) pair of the server this
       Connection is attempting to connect to.
    :param connection_id: The integer ID of the Connection in this Pool.

    .. versionadded:: 3.9
    r   Nr   r   r   r   r    rH   `  r   rH   c                   @  r   )rJ   a  Published when the driver checks in a Connection into the Pool.

    :param address: The address (host, port) pair of the server this
       Connection is attempting to connect to.
    :param connection_id: The integer ID of the Connection in this Pool.

    .. versionadded:: 3.9
    r   Nr   r   r   r   r    rJ   m  r   rJ   c                   @  sD   e Zd ZdZdZdd	d
ZedddZedddZdddZ	dS )_ServerEventzBase class for server events.)Z__server_address__topology_idserver_addressr   topology_idr
   r%   r&   c                 C     || _ || _d S r   )_ServerEvent__server_address_ServerEvent__topology_id)r+   r   r   r   r   r    r        
z_ServerEvent.__init__c                 C  r   )z+The address (host, port) pair of the server)r   r   r   r   r    r     r   z_ServerEvent.server_addressc                 C  r   z>A unique identifier for the topology this server is a part of.)r   r   r   r   r    r     r   z_ServerEvent.topology_idrb   c                 C      d| j j d| j d| j dS )N<  topology_id: >)r   r   r   r   r   r   r   r    r         z_ServerEvent.__repr__Nr   r   r   r
   r%   r&   r   r%   r
   r   )
r   r   r   r   r   r   r   r   r   r   r   r   r   r    r   z  s    
r   c                      L   e Zd ZdZdZd fd
dZedddZedddZdddZ	  Z
S )r[   zJPublished when server description changes.

    .. versionadded:: 3.3
    Z__previous_descriptionZ__new_descriptionprevious_descriptionr   new_descriptionargsr   r%   r&   c                      t  j|  || _|| _d S r   )r   r   4_ServerDescriptionChangedEvent__previous_description/_ServerDescriptionChangedEvent__new_descriptionr+   r  r  r  r   r   r    r     r   z&ServerDescriptionChangedEvent.__init__c                 C  r   )zUThe previous
        :class:`~pymongo.server_description.ServerDescription`.
        )r  r   r   r   r    r    r   z2ServerDescriptionChangedEvent.previous_descriptionc                 C  r   )zPThe new
        :class:`~pymongo.server_description.ServerDescription`.
        )r  r   r   r   r    r    r   z-ServerDescriptionChangedEvent.new_descriptionrb   c                 C  r   )Nz <{} {} changed from: {}, to: {}>)r   r   r   r   r  r  r   r   r   r    r     r   z&ServerDescriptionChangedEvent.__repr__)r  r   r  r   r  r   r%   r&   )r%   r   r   r   r   r   r   r   r   r   r  r  r   r   r   r   r   r    r[         
r[   c                   @  r   )rZ   zEPublished when server is initialized.

    .. versionadded:: 3.3
    r   Nr   r   r   r   r    rZ         rZ   c                   @  r   )r\   z@Published when server is closed.

    .. versionadded:: 3.3
    r   Nr   r   r   r   r    r\     r  r\   c                   @  r   )TopologyEventz+Base class for topology description events.)r   r   r
   r%   r&   c                 C  r   r   Z_TopologyEvent__topology_id)r+   r   r   r   r    r     r   zTopologyEvent.__init__c                 C  r   r  r  r   r   r   r    r     r   zTopologyEvent.topology_idrb   c                 C  s   d| j j d| j dS )Nr  r  r  )r   r   r   r   r   r   r    r     s   zTopologyEvent.__repr__Nr   r
   r%   r&   r	  r   )	r   r   r   r   r   r   r   r   r   r   r   r   r    r    s    
r  c                      r
  )rS   zPPublished when the topology description changes.

    .. versionadded:: 3.3
    r  r  r   r  r  r   r%   r&   c                   r  r   )r   r   6_TopologyDescriptionChangedEvent__previous_description1_TopologyDescriptionChangedEvent__new_descriptionr  r   r   r    r     r   z(TopologyDescriptionChangedEvent.__init__c                 C  r   )zYThe previous
        :class:`~pymongo.topology_description.TopologyDescription`.
        )r  r   r   r   r    r    r   z4TopologyDescriptionChangedEvent.previous_descriptionc                 C  r   )zTThe new
        :class:`~pymongo.topology_description.TopologyDescription`.
        )r  r   r   r   r    r    r   z/TopologyDescriptionChangedEvent.new_descriptionrb   c                 C  r   )Nz-<{} topology_id: {} changed from: {}, to: {}>)r   r   r   r   r  r  r   r   r   r    r     r   z(TopologyDescriptionChangedEvent.__repr__)r  r   r  r   r  r   r%   r&   )r%   r   r   r  r   r   r   r    rS     r  rS   c                   @  r   )rQ   zKPublished when the topology is initialized.

    .. versionadded:: 3.3
    r   Nr   r   r   r   r    rQ     r  rQ   c                   @  r   )rU   zFPublished when the topology is closed.

    .. versionadded:: 3.3
    r   Nr   r   r   r   r    rU     r  rU   c                   @  sF   e Zd ZdZdZddd
dZedddZedddZdddZ	dS )_ServerHeartbeatEventz'Base class for server heartbeat events.)r   Z	__awaitedFry   r   awaitedrr   r%   r&   c                 C  r   r   )$_ServerHeartbeatEvent__connection_id_ServerHeartbeatEvent__awaited)r+   ry   r  r   r   r    r     r   z_ServerHeartbeatEvent.__init__c                 C  r   )zSThe address (host, port) of the server this heartbeat was sent
        to.
        )r  r   r   r   r    ry   !  r   z#_ServerHeartbeatEvent.connection_idc                 C  r   )zgWhether the heartbeat was issued as an awaitable hello command.

        .. versionadded:: 4.6
        )r  r   r   r   r    r  (  r   z_ServerHeartbeatEvent.awaitedrb   c                 C  r  )Nr  r  z
 awaited: r  )r   r   ry   r  r   r   r   r    r   0  r  z_ServerHeartbeatEvent.__repr__NFry   r   r  rr   r%   r&   r   r   r   )
r   r   r   r   r   r   r   ry   r  r   r   r   r   r    r    s    r  c                   @  r   )rM   zFPublished when a heartbeat is started.

    .. versionadded:: 3.3
    r   Nr   r   r   r   r    rM   4  r  rM   c                      b   e Zd ZdZdZ	dd fddZedddZedddZed fddZ	dddZ
  ZS )rN   zIFired when the server heartbeat succeeds.

    .. versionadded:: 3.3
    r   r   Fr   floatr   r   ry   r   r  rr   r%   r&   c                      t  || || _|| _d S r   )r   r   (_ServerHeartbeatSucceededEvent__duration%_ServerHeartbeatSucceededEvent__replyr+   r   r   ry   r  r   r   r    r   E     
z&ServerHeartbeatSucceededEvent.__init__c                 C  r   z/The duration of this heartbeat in microseconds.)r%  r   r   r   r    r   L  r   z&ServerHeartbeatSucceededEvent.durationc                 C  r   )z-An instance of :class:`~pymongo.hello.Hello`.)r&  r   r   r   r    r   Q  r   z#ServerHeartbeatSucceededEvent.replyc                   r   zWhether the heartbeat was awaited.

        If true, then :meth:`duration` reflects the sum of the round trip time
        to the server and the time that the server waited before sending a
        response.

        .. versionadded:: 3.11
        r   r  r   r   r   r    r  V     
z%ServerHeartbeatSucceededEvent.awaitedrb   c                 C     d | jj| j| j| j| jS )Nz,<{} {} duration: {}, awaited: {}, reply: {}>r   r   r   ry   r   r  r   r   r   r   r    r   b     z&ServerHeartbeatSucceededEvent.__repr__r  )
r   r#  r   r   ry   r   r  rr   r%   r&   r%   r#  )r%   r   r   r   r   r   r   r   r   r   r   r   r   r  r   r   r   r   r   r    rN   =  s    rN   c                      r!  )rO   zxFired when the server heartbeat fails, either with an "ok: 0"
    or a socket exception.

    .. versionadded:: 3.3
    r"  Fr   r#  r   	Exceptionry   r   r  rr   r%   r&   c                   r$  r   )r   r   %_ServerHeartbeatFailedEvent__duration"_ServerHeartbeatFailedEvent__replyr'  r   r   r    r   u  r(  z#ServerHeartbeatFailedEvent.__init__c                 C  r   r)  )r3  r   r   r   r    r   |  r   z#ServerHeartbeatFailedEvent.durationc                 C  r   )zA subclass of :exc:`Exception`.)r4  r   r   r   r    r     r   z ServerHeartbeatFailedEvent.replyc                   r   r*  r+  r   r   r   r    r    r,  z"ServerHeartbeatFailedEvent.awaitedrb   c                 C  r-  )Nz.<{} {} duration: {}, awaited: {}, reply: {!r}>r.  r   r   r   r    r     r/  z#ServerHeartbeatFailedEvent.__repr__r  )
r   r#  r   r2  ry   r   r  rr   r%   r&   r0  )r%   r2  r   r   r1  r   r   r   r    rO   l  s    rO   c                   @  sl  e Zd ZdZdjddZedkdd	Zedkd
dZedkddZedkddZ	edkddZ
dlddZ		dmdnd$d%Z			&	'dodpd-d.Z			'dqdrd0d1Zdsd3d4Zdtd7d8Zdud:d;Zdvd?d@ZdvdAdBZdwdFdGZdxdHdIZdxdJdKZdydMdNZdzdRdSZd{dTdUZ	&d|d}dWdXZd{dYdZZd~d[d\Zdd]d^Zdd`daZd{dbdcZddddeZ ddfdgZ!d~dhdiZ"dS )_EventListenerszConfigure event listeners for a client instance.

    Any event listeners registered globally are included by default.

    :param listeners: A list of event listeners.
    rc   "Optional[Sequence[_EventListener]]c                 C  s  t jd d  | _t jd d  | _t j}|d d  | _t jd d  | _t j	d d  | _
|d urj|D ]9}t|tr=| j| t|trH| j| t|trS| j| t|tr^| j| t|tri| j
| q0t| j| _t| j| _t| j| _t| j| _t| j
| _d S r   )rl   r   "_EventListeners__command_listenersr   !_EventListeners__server_listenersr   +_EventListeners__server_heartbeat_listenersr   #_EventListeners__topology_listenersr   _EventListeners__cmap_listenersrg   r"   rm   rY   rL   rP   r3   rr   %_EventListeners__enabled_for_commands#_EventListeners__enabled_for_server-_EventListeners__enabled_for_server_heartbeat%_EventListeners__enabled_for_topology!_EventListeners__enabled_for_cmap)r+   rc   lstr   r   r    r     s0   




z_EventListeners.__init__r%   rr   c                 C  r   )z-Are any CommandListener instances registered?)r<  r   r   r   r    enabled_for_commands  r   z$_EventListeners.enabled_for_commandsc                 C  r   )z,Are any ServerListener instances registered?)r=  r   r   r   r    enabled_for_server  r   z"_EventListeners.enabled_for_serverc                 C  r   )z5Are any ServerHeartbeatListener instances registered?)r>  r   r   r   r    enabled_for_server_heartbeat  r   z,_EventListeners.enabled_for_server_heartbeatc                 C  r   )z.Are any TopologyListener instances registered?)r?  r   r   r   r    enabled_for_topology  r   z$_EventListeners.enabled_for_topologyc                 C  r   )z4Are any ConnectionPoolListener instances registered?)r@  r   r   r   r    enabled_for_cmap  r   z _EventListeners.enabled_for_cmaplist[_EventListeners]c                 C  s   | j | j | j | j | j S )z#List of registered event listeners.)r7  r9  r8  r:  r;  r   r   r   r    event_listeners  s   z_EventListeners.event_listenersNr   r   r~   rb   rx   r^   ry   r   r   r{   op_idr|   r}   r&   c           
   	   C  sX   |du r|}t |||||||d}| jD ]}	z|	| W q ty)   t  Y qw dS )a  Publish a CommandStartedEvent to all command listeners.

        :param command: The command document.
        :param database_name: The name of the database this command was run
            against.
        :param request_id: The request id for this operation.
        :param connection_id: The address (host, port) of the server this
            command was sent to.
        :param op_id: The (optional) operation id for this operation.
        :param service_id: The service_id this command was sent to, or ``None``.
        N)r|   r   )r$   r7  r,   r2  r   )
r+   r   r~   rx   ry   r   rI  r|   r#   
subscriberr   r   r    publish_command_start  s$   
	
z%_EventListeners.publish_command_startFrw   r   r   r   ro   speculative_helloc                 C  sd   |du r|}|	r
i }t ||||||||
|d	}| jD ]}z|| W q ty/   t  Y qw dS )a  Publish a CommandSucceededEvent to all command listeners.

        :param duration: The command duration as a datetime.timedelta.
        :param reply: The server reply document.
        :param command_name: The command name.
        :param request_id: The request id for this operation.
        :param connection_id: The address (host, port) of the server this
            command was sent to.
        :param op_id: The (optional) operation id for this operation.
        :param service_id: The service_id this command was sent to, or ``None``.
        :param speculative_hello: Was the command sent with speculative auth?
        :param database_name: The database this command was sent to, or ``""``.
        N)r~   r   )r.   r7  r/   r2  r   )r+   r   r   ro   rx   ry   r   rI  r|   rL  r~   r#   rJ  r   r   r    publish_command_success  s,   

z'_EventListeners.publish_command_successr   c
                 C  s\   |du r|}t ||||||||	|d	}
| jD ]}z||
 W q ty+   t  Y qw dS )a  Publish a CommandFailedEvent to all command listeners.

        :param duration: The command duration as a datetime.timedelta.
        :param failure: The server reply document or failure description
            document.
        :param command_name: The command name.
        :param request_id: The request id for this operation.
        :param connection_id: The address (host, port) of the server this
            command was sent to.
        :param op_id: The (optional) operation id for this operation.
        :param service_id: The service_id this command was sent to, or ``None``.
        :param database_name: The database this command was sent to, or ``""``.
        Nr   )r0   r7  r1   r2  r   )r+   r   r   ro   rx   ry   r   rI  r|   r~   r#   rJ  r   r   r    publish_command_failure7  s(   

z'_EventListeners.publish_command_failurer  c              	   C  @   t ||}| jD ]}z|| W q ty   t  Y qw dS )zPublish a ServerHeartbeatStartedEvent to all server heartbeat
        listeners.

        :param connection_id: The address (host, port) pair of the connection.
        :param awaited: True if this heartbeat is part of an awaitable hello command.
        N)rM   r9  r,   r2  r   )r+   ry   r  r#   rJ  r   r   r     publish_server_heartbeat_startedc     


z0_EventListeners.publish_server_heartbeat_startedr#  r   c              	   C  D   t ||||}| jD ]}z|| W q
 ty   t  Y q
w dS )a  Publish a ServerHeartbeatSucceededEvent to all server heartbeat
        listeners.

        :param connection_id: The address (host, port) pair of the connection.
        :param duration: The execution time of the event in the highest possible
            resolution for the platform.
        :param reply: The command reply.
        :param awaited: True if the response was awaited.
        N)rN   r9  r/   r2  r   r+   ry   r   r   r  r#   rJ  r   r   r    "publish_server_heartbeat_succeededq     

z2_EventListeners.publish_server_heartbeat_succeededr2  c              	   C  rR  )a  Publish a ServerHeartbeatFailedEvent to all server heartbeat
        listeners.

        :param connection_id: The address (host, port) pair of the connection.
        :param duration: The execution time of the event in the highest possible
            resolution for the platform.
        :param reply: The command reply.
        :param awaited: True if the response was awaited.
        N)rO   r9  r1   r2  r   rS  r   r   r    publish_server_heartbeat_failed  rU  z/_EventListeners.publish_server_heartbeat_failedr   r   r
   c              	   C  rO  )zPublish a ServerOpeningEvent to all server listeners.

        :param server_address: The address (host, port) pair of the server.
        :param topology_id: A unique identifier for the topology this server
           is a part of.
        N)rZ   r8  rR   r2  r   r+   r   r   r#   rJ  r   r   r    publish_server_opened  rQ  z%_EventListeners.publish_server_openedc              	   C  rO  )zPublish a ServerClosedEvent to all server listeners.

        :param server_address: The address (host, port) pair of the server.
        :param topology_id: A unique identifier for the topology this server
           is a part of.
        N)r\   r8  rV   r2  r   rW  r   r   r    publish_server_closed  rQ  z%_EventListeners.publish_server_closedr  r   r  c              	   C  sD   t ||||}| jD ]}z|| W q
 ty   t  Y q
w dS )a~  Publish a ServerDescriptionChangedEvent to all server listeners.

        :param previous_description: The previous server description.
        :param server_address: The address (host, port) pair of the server.
        :param new_description: The new server description.
        :param topology_id: A unique identifier for the topology this server
           is a part of.
        N)r[   r8  rT   r2  r   )r+   r  r  r   r   r#   rJ  r   r   r    "publish_server_description_changed  s   

z2_EventListeners.publish_server_description_changedc              	   C  >   t |}| jD ]}z|| W q ty   t  Y qw dS )zPublish a TopologyOpenedEvent to all topology listeners.

        :param topology_id: A unique identifier for the topology this server
           is a part of.
        N)rQ   r:  rR   r2  r   r+   r   r#   rJ  r   r   r    publish_topology_opened     

z'_EventListeners.publish_topology_openedc              	   C  r[  )zPublish a TopologyClosedEvent to all topology listeners.

        :param topology_id: A unique identifier for the topology this server
           is a part of.
        N)rU   r:  rV   r2  r   r\  r   r   r    publish_topology_closed  r^  z'_EventListeners.publish_topology_closedr   c              	   C  B   t |||}| jD ]}z|| W q	 ty   t  Y q	w dS )a:  Publish a TopologyDescriptionChangedEvent to all topology listeners.

        :param previous_description: The previous topology description.
        :param new_description: The new topology description.
        :param topology_id: A unique identifier for the topology this server
           is a part of.
        N)rS   r:  rT   r2  r   )r+   r  r  r   r#   rJ  r   r   r    $publish_topology_description_changed  s   

z4_EventListeners.publish_topology_description_changedr   r   r   c              	   C  rO  )z:Publish a :class:`PoolCreatedEvent` to all pool listeners.N)r4   r;  r5   r2  r   )r+   r   r   r#   rJ  r   r   r    publish_pool_created  s   


z$_EventListeners.publish_pool_createdc              	   C  r[  )z8Publish a :class:`PoolReadyEvent` to all pool listeners.N)r7   r;  r8   r2  r   r+   r   r#   rJ  r   r   r    publish_pool_ready     

z"_EventListeners.publish_pool_readyr   c              	   C  r`  )z:Publish a :class:`PoolClearedEvent` to all pool listeners.N)r9   r;  r:   r2  r   )r+   r   r|   r   r#   rJ  r   r   r    publish_pool_cleared  s   

z$_EventListeners.publish_pool_clearedc              	   C  r[  )z9Publish a :class:`PoolClosedEvent` to all pool listeners.N)r;   r;  r<   r2  r   rc  r   r   r    publish_pool_closed  re  z#_EventListeners.publish_pool_closedc              	   C  rO  )zWPublish a :class:`ConnectionCreatedEvent` to all connection
        listeners.
        N)r=   r;  r>   r2  r   r+   r   ry   r#   rJ  r   r   r    publish_connection_created"     


z*_EventListeners.publish_connection_createdc              	   C  r`  )zDPublish a :class:`ConnectionReadyEvent` to all connection listeners.N)r?   r;  r@   r2  r   r+   r   ry   r   r#   rJ  r   r   r    publish_connection_ready-     

z(_EventListeners.publish_connection_readyr   c              	   C  r`  )zVPublish a :class:`ConnectionClosedEvent` to all connection
        listeners.
        N)rB   r;  rC   r2  r   )r+   r   ry   r   r#   rJ  r   r   r    publish_connection_closed8  rm  z)_EventListeners.publish_connection_closedc              	   C  r[  )z_Publish a :class:`ConnectionCheckOutStartedEvent` to all connection
        listeners.
        N)rD   r;  rE   r2  r   rc  r   r   r    $publish_connection_check_out_startedC  s   

z4_EventListeners.publish_connection_check_out_startedc              	   C  r`  )z^Publish a :class:`ConnectionCheckOutFailedEvent` to all connection
        listeners.
        N)rF   r;  rG   r2  r   )r+   r   r   r   r#   rJ  r   r   r    #publish_connection_check_out_failedN     

z3_EventListeners.publish_connection_check_out_failedc              	   C  r`  )zZPublish a :class:`ConnectionCheckedOutEvent` to all connection
        listeners.
        N)rH   r;  rI   r2  r   rk  r   r   r    publish_connection_checked_out[  rq  z._EventListeners.publish_connection_checked_outc              	   C  rO  )zYPublish a :class:`ConnectionCheckedInEvent` to all connection
        listeners.
        N)rJ   r;  rK   r2  r   rh  r   r   r    publish_connection_checked_inh  rj  z-_EventListeners.publish_connection_checked_in)rc   r6  r   )r%   rG  r   )r   r   r~   rb   rx   r^   ry   r   r   r{   rI  r{   r|   r}   r%   r&   )NNFrw   )r   r   r   r   ro   rb   rx   r^   ry   r   r   r{   rI  r{   r|   r}   rL  rr   r~   rb   r%   r&   )NNrw   )r   r   r   r   ro   rb   rx   r^   ry   r   r   r{   rI  r{   r|   r}   r~   rb   r%   r&   r   )
ry   r   r   r#  r   r   r  rr   r%   r&   )
ry   r   r   r#  r   r2  r  rr   r%   r&   r  )
r  r   r  r   r   r   r   r
   r%   r&   r  )r  r   r  r   r   r
   r%   r&   r   r   r  r   r   )r   r   ry   r^   r   r#  r%   r&   )r   r   ry   r^   r   rb   r%   r&   )r   r   r   rb   r   r#  r%   r&   )#r   r   r   r   r   r   rB  rC  rD  rE  rF  rH  rK  rM  rN  rP  rT  rV  rX  rY  rZ  r]  r_  ra  rb  rd  rf  rg  ri  rl  rn  ro  rp  rr  rs  r   r   r   r    r5    s^    

.9
,









	

	




r5  )r]   r   r%   r^   )ra   rb   rc   rd   r%   rd   )rj   r   r%   r&   )ro   rb   rp   rq   r%   rr   )Kr   
__future__r   datetimecollectionsr   r   typingr   r   r   r   r	   Zbson.objectidr
   Zpymongo.hellor   r   Zpymongo.helpers_sharedr   r   Zpymongo.typingsr   r   r   Zpymongo.server_descriptionr   Zpymongo.topology_descriptionr   r   rl   r   r"   r3   rL   rP   rY   r`   rk   rn   rt   ru   r$   r.   r0   r   r4   r7   r9   r;   r   r   r   r   r   r=   r?   rB   rD   rF   rH   rJ   r   r[   rZ   r\   r  rS   rQ   rU   r  rM   rN   rO   r5  r   r   r   r    <module>   s~    /x



	LCEC-#)		)			/0