o
    hhN                     @  s  d Z ddlm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	m
Z
mZ ddlmZmZ ddlmZ ddlmZ ddlmZmZ dd	lmZ dd
lmZ ddlmZmZmZ ddlmZ ddl m!Z! ddl"m#Z# ddl$m%Z% e	rddl&m'Z'm(Z(m)Z) ddl*m+Z+ ddl,m-Z- dZ.d1ddZ/d2ddZ0G dd dZ1G d d! d!e1Z2G d"d# d#e1Z3G d$d% d%e1Z4e5 Z6d3d'd(Z7d4d+d,Z8d5d-d.Z9d5d/d0Z:e.re;e: dS dS )6z9Class to monitor a MongoDB server on a background thread.    )annotationsN)TYPE_CHECKINGAnyOptional)commonperiodic_executor)MovingMinimum)_SrvResolver)NetworkTimeout_OperationCancelled)Hello)_async_create_lock)_SDAM_LOGGER
_debug_log_SDAMStatusMessage)_shutdown_executors)_is_faas)MovingAverage)ServerDescription)AsyncConnectionPool_CancellationContext)TopologySettings)TopologyFerror	ExceptionreturnNonec                 C  s   d| _ d| _d| _dS )z'PYTHON-2433 Clear error traceback info.N)__traceback____context__	__cause__r    r"   O/var/www/html/venv/lib/python3.10/site-packages/pymongo/asynchronous/monitor.py	_sanitize2   s   
r$   startfloatc                 C  s   t dt |  S )zReturn the duration since the given start time.

    Accounts for buggy platforms where time.monotonic() is not monotonic.
    See PYTHON-4600.
    g        )maxtime	monotonic)r%   r"   r"   r#   _monotonic_duration9   s   r*   c                   @  sH   e 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S )MonitorBasetopologyr   namestrintervalintmin_intervalr&   c                   s^   d fdd}t j||||d}|| _dd fd
d}t| |j t||| _t|  dS )zBase class to do periodic work on a background thread.

        The background thread is signaled to stop when the Topology or
        this instance is freed.
        r   boolc                    s&     } | d u r
dS |   I d H  dS )NFT)_run)monitorZself_refr"   r#   targetL   s   z$MonitorBase.__init__.<locals>.target)r/   r1   r6   r-   NdummyOptional[Topology]r   c                   s     }|r|   d S d S Ngc_safe_close)r7   r4   r5   r"   r#   _on_topology_gcY   s   z-MonitorBase.__init__.<locals>._on_topology_gc)r   r2   r9   )r7   r8   r   r   )	r   ZAsyncPeriodicExecutor	_executorweakrefrefcloseproxy	_topology	_register)selfr,   r-   r/   r1   r6   executorr<   r"   r5   r#   __init__C   s   	zMonitorBase.__init__r   r   c                 C     | j   dS )z[Start monitoring, or restart after a fork.

        Multiple calls have no effect.
        N)r=   openrD   r"   r"   r#   rH   e   s   zMonitorBase.openc                 C  rG   )zGC safe close.N)r=   r@   rI   r"   r"   r#   r;   l      zMonitorBase.gc_safe_closec                   s   |    dS )zWClose and stop monitoring.

        open() restarts the monitor after closing.
        Nr:   rI   r"   r"   r#   r@   p   s   zMonitorBase.closec                   s   | j  I dH  dS )zWait for the monitor to stop.N)r=   joinrI   r"   r"   r#   rK   w      zMonitorBase.joinc                 C  rG   )z)If the monitor is sleeping, wake it soon.N)r=   ZwakerI   r"   r"   r#   request_check{   rJ   zMonitorBase.request_checkN)r,   r   r-   r.   r/   r0   r1   r&   r   r   )	__name__
__module____qualname__rF   rH   r;   r@   rK   rM   r"   r"   r"   r#   r+   B   s    

"


r+   c                      s   e Zd Zd$ f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d&ddZd'd"d#Z  ZS )(Monitorserver_descriptionr   r,   r   poolr   topology_settingsr   c                   s   t  |d|jtj || _|| _|| _| jjj	| _
| j
duo"| j
j| _d| _d| _t||||j| _|jdkr?d| _dS |jdkrId| _dS t  | _dS )a   Class to monitor a MongoDB server on a background thread.

        Pass an initial ServerDescription, a Topology, a Pool, and
        TopologySettings.

        The Topology is weakly referenced. The Pool must be exclusive to this
        Monitor.
        Zpymongo_server_monitor_taskNstreamTpollF)superrF   heartbeat_frequencyr   MIN_HEARTBEAT_INTERVAL_server_description_pool	_settingsZ_pool_optionsZ_event_listeners
_listenersZenabled_for_server_heartbeat_publish_cancel_context_conn_id_RttMonitorZ_create_pool_for_monitoraddress_rtt_monitorZserver_monitoring_mode_streamr   )rD   rS   r,   rT   rU   	__class__r"   r#   rF      s.   




zMonitor.__init__r   r   c                 C  s   | j }|r|  dS dS )zCancel any concurrent hello check.

        Note: this is called from a weakref.proxy callback and MUST NOT take
        any locks.
        N)r`   cancel)rD   contextr"   r"   r#   cancel_check   s   zMonitor.cancel_checkc                   s,   | j   | jjr| j  I dH  dS dS )z1Start an _RttMonitor that periodically runs ping.N)rd   rH   r=   _stoppedr@   rI   r"   r"   r#   _start_rtt_monitor   s
   
zMonitor._start_rtt_monitorc                 C  s    | j   | j  |   d S r9   )r=   r@   rd   r;   rj   rI   r"   r"   r#   r;      s   

zMonitor.gc_safe_closec                   s(   t j| j | j ddI d H  d S )NT)Zreturn_exceptions)asyncioZgatherr=   rK   rd   rI   r"   r"   r#   rK      s   zMonitor.joinc                   s,   |    | j I d H  |  I d H  d S r9   )r;   rd   r@   _reset_connectionrI   r"   r"   r#   r@      s   zMonitor.closec                   s   | j  I d H  d S r9   )r\   resetrI   r"   r"   r#   rn      rL   zMonitor._reset_connectionc              
     sb  zz| j }z
|  I d H | _ W n8 tyH } z,t| t| j j|d| _ |jr-| j  W Y d }~W W | jj	rB| j
 I d H  d S d S d }~ww | jj| j | j jt| j jtdI d H  | jrt| j jrt| j jrt|  I d H  | j  | j jr|jr| j  W n ty   |  I d H  Y nw W | jj	r| j
 I d H  d S d S | jj	r| j
 I d H  w w )Nr!   )Z
reset_poolZinterrupt_connections)r[   _check_serverr   r$   r   rc   is_server_type_knownr=   Z
skip_sleeprk   rd   r@   rB   Z	on_changer   
isinstancer
   re   topology_versionrl   ReferenceError)rD   Zprev_sdexcr"   r"   r#   r3      sT   


zMonitor._runc                   s  d| _ t }z|  I dH W S  ty     ty } zjt| | j}|j}t	|}t
| jo6|jo6|j}| jrK| jdusBJ | j|||| ttjrhtttj| jj|d |d ||d || j d	 |  I dH  t|tru | j I dH  t||dW  Y d}~S d}~ww )z^Call hello or read the next streaming response.

        Returns a ServerDescription.
        Nr        )message
topologyId
serverHost
serverPortawaited
durationMSZfailuredriverConnectionIdr!   ) ra   r(   r)   _check_oncert   r   r$   r[   rc   r*   r2   re   rq   rs   r_   r^   Zpublish_server_heartbeat_failedr   isEnabledForloggingDEBUGr   r   ZHEARTBEAT_FAILrB   _topology_idrn   rr   r   rd   ro   r   )rD   r%   r   sdrc   durationr|   r"   r"   r#   rp      sF   
zMonitor._check_serverc           	        s  | j j}| j }t| jjo| jo|jo|j}| jr(| j	dus!J | j	
|| | jr6| jjr6|  I dH  | j 4 I dH }ttjr[tttj| jj|j|j|d |d |d |j| _|j| _| |I dH \}}|jsy| j|I dH  | j  I dH \}}t!||||d}| jr| j	dusJ | j	"||||j ttjrtttj#| jj|j|j|d |d ||d |j$d
 |W  d  I dH  S 1 I dH sw   Y  dS )zfA single attempt to call hello.

        Returns a ServerDescription, or raises an exception.
        Nr   rv   )rx   ry   r~   serverConnectionIdrz   r{   r|   )Zmin_round_trip_timerw   )	rx   ry   r~   r   rz   r{   r|   r}   Zreply)%r[   rc   r2   r\   Zconnsre   rq   rs   r_   r^   Z publish_server_heartbeat_startedr`   Z	cancelledrn   checkoutr   r   r   r   r   r   ZHEARTBEAT_STARTrB   r   idZserver_connection_idZcancel_contextra   _check_with_socket	awaitablerd   
add_samplegetr   Z"publish_server_heartbeat_succeededZHEARTBEAT_SUCCESSZdocument)	rD   rc   r   r|   connresponseZround_trip_timeZavg_rttZmin_rttr"   r"   r#   r   %  sd   
0zMonitor._check_oncer   r   tuple[Hello, float]c                   sz   t  }|jrt| I dH dd}n!| jr,|jr,| jjr,|	| jj| j
jI dH }n	|	ddI dH }t|}||fS )zcReturn (Hello, round_trip_time).

        Can raise ConnectionFailure or OperationFailure.
        NT)r   )r(   r)   Zmore_to_comer   Z_next_replyre   Zperformed_handshaker[   rs   Z_hellor]   rY   r*   )rD   r   r%   r   r   r"   r"   r#   r   b  s"   zMonitor._check_with_socket)rS   r   r,   r   rT   r   rU   r   rN   )r   r   )r   r   r   r   )rO   rP   rQ   rF   rj   rl   r;   rK   r@   rn   r3   rp   r   r   __classcell__r"   r"   rf   r#   rR      s    
(

	




*
'=rR   c                      s2   e Zd Zd fddZdd	d
ZdddZ  ZS )
SrvMonitorr,   r   rU   r   c                   sP   t  |dtj|j || _| jj| _t| jj	t
sJ | jj	| _t | _dS )zClass to poll SRV records on a background thread.

        Pass a Topology and a TopologySettings.

        The Topology is weakly referenced.
        Zpymongo_srv_polling_threadN)rX   rF   r   MIN_SRV_RESCAN_INTERVALrY   r]   Z_seeds	_seedlistrr   Zfqdnr.   _fqdnr(   r)   _startup_time)rD   r,   rU   rf   r"   r#   rF   {  s   

zSrvMonitor.__init__r   r   c                   st   t  | jtj k rd S |  I d H }|r8|| _z| j| jI d H  W d S  t	y7   | 
 I d H  Y d S w d S r9   )r(   r)   r   r   r   _get_seedlistr   rB   Zon_srv_updatert   r@   )rD   seedlistr"   r"   r#   r3     s   zSrvMonitor._runOptional[list[tuple[str, Any]]]c                   sv   zt | j| jjj| jj}| I dH \}}t|dkrtW n ty.   | 	  Y dS w | j
t|tj |S )zXPoll SRV records for a seedlist.

        Returns a list of ServerDescriptions.
        Nr   )r	   r   r]   Zpool_optionsconnect_timeoutZsrv_service_nameZget_hosts_and_min_ttllenr   rM   r=   Zupdate_intervalr'   r   r   )rD   resolverr   ttlr"   r"   r#   r     s"   zSrvMonitor._get_seedlist)r,   r   rU   r   rN   )r   r   )rO   rP   rQ   rF   r3   r   r   r"   r"   rf   r#   r   z  s    
r   c                      sZ   e Zd Zd f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	  Z
S )rb   r,   r   rU   r   rT   r   c                   s8   t  |d|jtj || _t | _t | _	t
 | _dS )z\Maintain round trip times for a server.

        The Topology is weakly referenced.
        Zpymongo_server_rtt_taskN)rX   rF   rY   r   rZ   r\   r   _moving_averager   _moving_minr   _lock)rD   r,   rU   rT   rf   r"   r#   rF     s   z_RttMonitor.__init__r   r   c                   s   |    | j I d H  d S r9   )r;   r\   ro   rI   r"   r"   r#   r@     s   z_RttMonitor.closesampler&   c              	     sZ   | j 4 I dH  | j| | j| W d  I dH  dS 1 I dH s&w   Y  dS )zAdd a RTT sample.N)r   r   r   r   )rD   r   r"   r"   r#   r     s
   .z_RttMonitor.add_sampletuple[Optional[float], float]c              	     sT   | j 4 I dH  | j | j fW  d  I dH  S 1 I dH s#w   Y  dS )zBGet the calculated average, or None if no samples yet and the min.N)r   r   r   r   rI   r"   r"   r#   r     s   0z_RttMonitor.getc              	     sV   | j 4 I dH  | j  | j  W d  I dH  dS 1 I dH s$w   Y  dS )zReset the average RTT.N)r   r   ro   r   rI   r"   r"   r#   ro     s
   
.z_RttMonitor.resetc                   sl   z|   I d H }| |I d H  W d S  ty$   |  I d H  Y d S  ty5   | j I d H  Y d S w r9   )_pingr   rt   r@   r   r\   ro   )rD   Zrttr"   r"   r#   r3     s   z_RttMonitor._runc              	     sr   | j  4 I dH "}| jjrtdt }| I dH  t|W  d  I dH  S 1 I dH s2w   Y  dS )z)Run a "hello" command and return the RTT.Nz_RttMonitor closed)	r\   r   r=   rk   r   r(   r)   Zhellor*   )rD   r   r%   r"   r"   r#   r     s   0z_RttMonitor._ping)r,   r   rU   r   rT   r   rN   )r   r&   r   r   )r   r   )r   r&   )rO   rP   rQ   rF   r@   r   r   ro   r3   r   r   r"   r"   rf   r#   rb     s    




rb   r4   c                 C  s   t | t}t| d S r9   )r>   r?   _unregister	_MONITORSadd)r4   r?   r"   r"   r#   rC     s   rC   monitor_ref"weakref.ReferenceType[MonitorBase]c                 C  s   t |  d S r9   )r   remove)r   r"   r"   r#   r     s   r   c                  C  s8   t d u rd S tt } | D ]}| }|r|  qd }d S r9   )r   listr;   )Zmonitorsr?   r4   r"   r"   r#   _shutdown_monitors  s   r   c                  C  s$   t } | r|   t} | r|   d S d S r9   )r   r   )shutdownr"   r"   r#   _shutdown_resources  s   
r   )r   r   r   r   )r%   r&   r   r&   )r4   r+   r   r   )r   r   r   r   rN   )<__doc__
__future__r   rm   atexitr   r(   r>   typingr   r   r   Zpymongor   r   Zpymongo._csotr   Z!pymongo.asynchronous.srv_resolverr	   Zpymongo.errorsr
   r   Zpymongo.hellor   Zpymongo.lockr   Zpymongo.loggerr   r   r   Zpymongo.periodic_executorr   Zpymongo.pool_optionsr   Zpymongo.read_preferencesr   Zpymongo.server_descriptionr   Zpymongo.asynchronous.poolr   r   r   Zpymongo.asynchronous.settingsr   Zpymongo.asynchronous.topologyr   Z_IS_SYNCr$   r*   r+   rR   r   rb   setr   rC   r   r   r   registerr"   r"   r"   r#   <module>   sN   

	> {<C




