o
    {gL                     @  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mZm	Z	m
Z
mZmZ ddlmZ ddlmZ ddlmZmZ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% 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l0m1Z1 dZ2d2ddZ3d3ddZ4G dd  d Z5G d!d" d"e5Z6G d#d$ d$e5Z7G d%d& d&e5Z8e9 Z:d4d(d)Z;d5d,d-Z<d6d.d/Z=d6d0d1Z>e?e> dS )7z9Class to monitor a MongoDB server on a background thread.    )annotationsN)TYPE_CHECKINGAnyMappingOptionalcast)common)MovingMinimum)NetworkTimeoutNotPrimaryErrorOperationFailure_OperationCancelled)Hello)_create_lock)_SDAM_LOGGER
_debug_log_SDAMStatusMessage)_is_faas)MovingAverage)ServerDescription)_SrvResolver)periodic_executor)_shutdown_executors)
ConnectionPool_CancellationContext)TopologySettings)TopologyTerror	ExceptionreturnNonec                 C  s   d| _ d| _d| _dS )z'PYTHON-2433 Clear error traceback info.N)__traceback____context__	__cause__r    r&   x/var/www/bot.gig.net.ua/public_html/telegram/P1/HellBot/venv/lib/python3.10/site-packages/pymongo/synchronous/monitor.py	_sanitize.   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_duration5   s   r.   c                   @  sJ   e Zd Zdd	d
ZdddZdddZdddZd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 |    dS )NFT)_run)monitorself_refr&   r'   targetH   s
   z$MonitorBase.__init__.<locals>.target)r3   r5   r;   r1   NdummyOptional[Topology]r!   c                   s     }|r|   d S d S Ngc_safe_close)r<   r8   r9   r&   r'   _on_topology_gcU   s   z-MonitorBase.__init__.<locals>._on_topology_gc)r    r6   r>   )r<   r=   r    r!   )	r   PeriodicExecutor	_executorweakrefrefcloseproxy	_topology	_register)selfr0   r1   r3   r5   r;   executorrA   r&   r9   r'   __init__?   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)rC   openrJ   r&   r&   r'   rN   a   s   zMonitorBase.openc                 C  rM   )zGC safe close.N)rC   rF   rO   r&   r&   r'   r@   h      zMonitorBase.gc_safe_closec                 C  s   |    dS )zWClose and stop monitoring.

        open() restarts the monitor after closing.
        Nr?   rO   r&   r&   r'   rF   l   s   zMonitorBase.closeNtimeoutOptional[int]c                 C  s   | j | dS )zWait for the monitor to stop.N)rC   join)rJ   rQ   r&   r&   r'   rS   s   s   zMonitorBase.joinc                 C  rM   )z)If the monitor is sleeping, wake it soon.N)rC   wakerO   r&   r&   r'   request_checkw   rP   zMonitorBase.request_check)r0   r   r1   r2   r3   r4   r5   r*   r    r!   r>   )rQ   rR   r    r!   )	__name__
__module____qualname__rL   rN   r@   rF   rS   rU   r&   r&   r&   r'   r/   >   s    

"

r/   c                      sx   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  ZS )&Monitorserver_descriptionr   r0   r   poolr   topology_settingsr   c                   s   t  |d|jtj || _|| _|| _| jjj	| _
| j
duo"| j
j| _d| _t||||j| _|jdkr<d| _dS |jdkrFd| _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.
        pymongo_server_monitor_threadNstreamTpollF)superrL   heartbeat_frequencyr   MIN_HEARTBEAT_INTERVAL_server_description_pool	_settings_pool_options_event_listeners
_listenersenabled_for_server_heartbeat_publish_cancel_context_RttMonitor_create_pool_for_monitoraddress_rtt_monitorserver_monitoring_mode_streamr   )rJ   r[   r0   r\   r]   	__class__r&   r'   rL   }   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)rl   cancel)rJ   contextr&   r&   r'   cancel_check   s   zMonitor.cancel_checkc                 C  s$   | j   | jjr| j   dS dS )z1Start an _RttMonitor that periodically runs ping.N)rp   rN   rC   _stoppedrF   rO   r&   r&   r'   _start_rtt_monitor   s   
zMonitor._start_rtt_monitorc                 C  s    | j   | j  |   d S r>   )rC   rF   rp   r@   rw   rO   r&   r&   r'   r@      s   

zMonitor.gc_safe_closec                 C  s   |    | j  |   d S r>   )r@   rp   rF   _reset_connectionrO   r&   r&   r'   rF      s   
zMonitor.closec                 C  s   | j   d S r>   )re   resetrO   r&   r&   r'   rz      rP   zMonitor._reset_connectionc              
   C  s   zn| j }z|  | _ W n) ty4 } zt| t| j j|d| _ |jr(| j  W Y d }~W d S d }~ww | j	j
| j | j jt| j jtd | jrZ| j jrZ| j jrZ|   | j  | j jri|jrl| j  W d S W d S W d S  ty|   |   Y d S w )Nr%   )
reset_poolinterrupt_connections)rd   _check_serverr   r(   r   ro   is_server_type_knownrC   
skip_sleeprH   	on_changer   
isinstancer
   rr   topology_versionry   ReferenceErrorrF   )rJ   prev_sdexcr&   r&   r'   r7      s@   

zMonitor._runc           	      C  sF  t  }z)z|  W W S  ttfy- } zttttf |j	}| j
|d  d}~ww  ty5     ty } zbt| | j}|j}t|}t| joS|joS|j}| jrh| jdus_J | j|||| ttjrtt| j
j|d |d ||d |t j!d | "  t#|t$r | j%&  t'||dW  Y d}~S d}~ww )z^Call hello or read the next streaming response.

        Returns a ServerDescription.
        z$clusterTimeNr        )
topologyId
serverHost
serverPortawaited
durationMSfailuremessager%   )(r,   r-   _check_oncer   r   r   r   r2   r   detailsrH   receive_cluster_timegetr   r   r(   rd   ro   r.   r6   rr   r   r   rk   ri   publish_server_heartbeat_failedr   isEnabledForloggingDEBUGr   _topology_idr   HEARTBEAT_FAILrz   r   r   rp   r{   r   )	rJ   r)   r   r   r   sdro   durationr   r&   r&   r'   r~      sN   


zMonitor._check_serverc           	      C  sz  | j j}| j }t| jjo| jo|jo|j}| jr'| j	dus J | j	
|| | jr2| jjr2|   | j |}ttjrStt| jj|j|j|d |d |tjd |j| _| |\}}|jsg| j| | j \}}t ||||d}| jr| j	dusJ | j	!||||j ttjrtt| jj|j|j|d |d ||d |j"tj#d
 |W  d   S 1 sw   Y  dS )zfA single attempt to call hello.

        Returns a ServerDescription, or raises an exception.
        Nr   r   )r   driverConnectionIdserverConnectionIdr   r   r   r   )min_round_trip_timer   )	r   r   r   r   r   r   r   replyr   )$rd   ro   r6   re   connsrr   r   r   rk   ri    publish_server_heartbeat_startedrl   	cancelledrz   checkoutr   r   r   r   r   rH   r   idserver_connection_idr   HEARTBEAT_STARTcancel_context_check_with_socket	awaitablerp   
add_sampler   r   "publish_server_heartbeat_succeededdocumentHEARTBEAT_SUCCESS)	rJ   ro   r   r   connresponseround_trip_timeavg_rttmin_rttr&   r&   r'   r     s`   
$zMonitor._check_oncer   r   tuple[Hello, float]c                 C  st   | j  }t }|jrt| dd}n| jr+|jr+| j	j
r+||| j	j
| jj}n||dd}t|}||fS )zcReturn (Hello, round_trip_time).

        Can raise ConnectionFailure or OperationFailure.
        T)r   N)rH   max_cluster_timer,   r-   more_to_comer   _next_replyrr   performed_handshakerd   r   _hellorf   rb   r.   )rJ   r   cluster_timer)   r   r   r&   r&   r'   r   W  s$   
zMonitor._check_with_socket)r[   r   r0   r   r\   r   r]   r   rV   )r    r   )r   r   r    r   )rW   rX   rY   rL   rw   ry   r@   rF   rz   r7   r~   r   r   __classcell__r&   r&   rs   r'   rZ   |   s    
'

	



'
+;rZ   c                      s2   e Zd Zd fddZdd	d
ZdddZ  ZS )
SrvMonitorr0   r   r]   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.
        pymongo_srv_polling_threadN)ra   rL   r   MIN_SRV_RESCAN_INTERVALrb   rf   _seeds	_seedlistr   fqdnr2   _fqdnr,   r-   _startup_time)rJ   r0   r]   rs   r&   r'   rL   r  s   

zSrvMonitor.__init__r    r!   c                 C  s`   t  | jtj k rd S |  }|r.|| _z
| j| j W d S  t	y-   | 
  Y d S w d S r>   )r,   r-   r   r   r   _get_seedlistr   rH   on_srv_updater   rF   )rJ   seedlistr&   r&   r'   r7     s   zSrvMonitor._runOptional[list[tuple[str, Any]]]c                 C  sn   zt | j| jjj| jj}| \}}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.
        r   N)r   r   rf   pool_optionsconnect_timeoutsrv_service_nameget_hosts_and_min_ttllenr   rU   rC   update_intervalr+   r   r   )rJ   resolverr   ttlr&   r&   r'   r     s    zSrvMonitor._get_seedlist)r0   r   r]   r   rV   )r    r   )rW   rX   rY   rL   r7   r   r   r&   r&   rs   r'   r   q  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 )rm   r0   r   r]   r   r\   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.
        pymongo_server_rtt_threadN)ra   rL   rb   r   rc   re   r   _moving_averager	   _moving_minr   _lock)rJ   r0   r]   r\   rs   r&   r'   rL     s   z_RttMonitor.__init__r    r!   c                 C  s   |    | j  d S r>   )r@   re   r{   rO   r&   r&   r'   rF     s   z_RttMonitor.closesampler*   c                 C  sD   | j  | j| | j| W d   dS 1 sw   Y  dS )zAdd a RTT sample.N)r   r   r   r   )rJ   r   r&   r&   r'   r     s   "z_RttMonitor.add_sampletuple[Optional[float], float]c                 C  s>   | j  | j | j fW  d   S 1 sw   Y  dS )zBGet the calculated average, or None if no samples yet and the min.N)r   r   r   r   rO   r&   r&   r'   r     s   $z_RttMonitor.getc                 C  s@   | j  | j  | j  W d   dS 1 sw   Y  dS )zReset the average RTT.N)r   r   r{   r   rO   r&   r&   r'   r{     s   
"z_RttMonitor.resetc                 C  sR   z|   }| | W d S  ty   |   Y d S  ty(   | j  Y d S w r>   )_pingr   r   rF   r   re   r{   )rJ   rttr&   r&   r'   r7     s   z_RttMonitor._runc                 C  sV   | j  }| jjrtdt }|  t|W  d   S 1 s$w   Y  dS )z)Run a "hello" command and return the RTT.z_RttMonitor closedN)	re   r   rC   rx   r   r,   r-   hellor.   )rJ   r   r)   r&   r&   r'   r     s   $z_RttMonitor._ping)r0   r   r]   r   r\   r   rV   )r   r*   r    r!   )r    r   )r    r*   )rW   rX   rY   rL   rF   r   r   r{   r7   r   r   r&   r&   rs   r'   rm     s    




rm   r8   c                 C  s   t | t}t| d S r>   )rD   rE   _unregister	_MONITORSadd)r8   rE   r&   r&   r'   rI     s   rI   monitor_ref"weakref.ReferenceType[MonitorBase]c                 C  s   t |  d S r>   )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 r>   )r   listr@   )monitorsrE   r8   r&   r&   r'   _shutdown_monitors  s   r   c                  C  s$   t } | r|   t} | r|   d S d S r>   )r   r   )shutdownr&   r&   r'   _shutdown_resources  s   
r   )r   r   r    r!   )r)   r*   r    r*   )r8   r/   r    r!   )r   r   r    r!   rV   )@__doc__
__future__r   atexitr   r,   rD   typingr   r   r   r   r   pymongor   pymongo._csotr	   pymongo.errorsr
   r   r   r   pymongo.hellor   pymongo.lockr   pymongo.loggerr   r   r   pymongo.pool_optionsr   pymongo.read_preferencesr   pymongo.server_descriptionr   pymongo.srv_resolverr   pymongo.synchronousr   %pymongo.synchronous.periodic_executorr   pymongo.synchronous.poolr   r   r   pymongo.synchronous.settingsr   pymongo.synchronous.topologyr   _IS_SYNCr(   r.   r/   rZ   r   rm   setr   rI   r   r   r   registerr&   r&   r&   r'   <module>   sJ   

	> v<C




