o
    'hL                     @  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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% 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)NetworkTimeout_OperationCancelled)Hello)_create_lock)_SDAM_LOGGER
_debug_log_SDAMStatusMessage)_shutdown_executors)_is_faas)MovingAverage)ServerDescription)_SrvResolver)
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"   W/var/www/html/olx_land/venv/lib/python3.10/site-packages/pymongo/synchronous/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 |    dS )NFT)_run)monitorself_refr"   r#   targetL   s
   z$MonitorBase.__init__.<locals>.target)r/   r1   r7   r-   NdummyOptional[Topology]r   c                   s     }|r|   d S d S Ngc_safe_close)r8   r4   r5   r"   r#   _on_topology_gcY   s   z-MonitorBase.__init__.<locals>._on_topology_gc)r   r2   r:   )r8   r9   r   r   )	r   PeriodicExecutor	_executorweakrefrefcloseproxy	_topology	_register)selfr,   r-   r/   r1   r7   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rF   r"   r"   r#   rJ   e   s   zMonitorBase.openc                 C  rI   )zGC safe close.N)r?   rB   rK   r"   r"   r#   r<   l      zMonitorBase.gc_safe_closec                 C  s   |    dS )zWClose and stop monitoring.

        open() restarts the monitor after closing.
        Nr;   rK   r"   r"   r#   rB   p   s   zMonitorBase.closec                 C  rI   )zWait for the monitor to stop.N)r?   joinrK   r"   r"   r#   rM   w   rL   zMonitorBase.joinc                 C  rI   )z)If the monitor is sleeping, wake it soon.N)r?   wakerK   r"   r"   r#   request_check{   rL   zMonitorBase.request_checkN)r,   r   r-   r.   r/   r0   r1   r&   r   r   )	__name__
__module____qualname__rH   rJ   r<   rB   rM   rO   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.
        pymongo_server_monitor_threadNstreamTpollF)superrH   heartbeat_frequencyr   MIN_HEARTBEAT_INTERVAL_server_description_pool	_settings_pool_options_event_listeners
_listenersenabled_for_server_heartbeat_publish_cancel_context_conn_id_RttMonitor_create_pool_for_monitoraddress_rtt_monitorserver_monitoring_mode_streamr   )rF   rU   r,   rV   rW   	__class__r"   r#   rH      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)rf   cancel)rF   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)rk   rJ   r?   _stoppedrB   rK   r"   r"   r#   _start_rtt_monitor   s   
zMonitor._start_rtt_monitorc                 C  s    | j   | j  |   d S r:   )r?   rB   rk   r<   rr   rK   r"   r"   r#   r<      s   

zMonitor.gc_safe_closec                 C  s    t j| j | j dd d S )NT)return_exceptions)asynciogatherr?   rM   rk   rK   r"   r"   r#   rM      s    zMonitor.joinc                 C  s   |    | j  |   d S r:   )r<   rk   rB   _reset_connectionrK   r"   r"   r#   rB      s   
zMonitor.closec                 C  s   | j   d S r:   )r_   resetrK   r"   r"   r#   rx      rL   zMonitor._reset_connectionc              
   C  s6  zzs| j }z|  | _ W n5 tyA } z)t| t| j j|d| _ |jr)| j  W Y d }~W W | jj	r;| j
  d S d S d }~ww | jj| j | j jt| j jtd | jrg| j jrg| j jrg|   | j  | j jrs|jrs| j  W n ty   |   Y nw W | jj	r| j
  d S d S | jj	r| j
  w w )Nr!   )
reset_poolinterrupt_connections)r^   _check_serverr
   r$   r   rj   is_server_type_knownr?   
skip_sleeprs   rk   rB   rD   	on_changer   
isinstancer	   rm   topology_versionrt   ReferenceError)rF   prev_sdexcr"   r"   r#   r3      sR   


zMonitor._runc                 C  s  d| _ t }z|  W S  ty     ty } zdt| | j}|j}t	|}t
| jo2|jo2|j}| jrG| jdus>J | j|||| ttjrdtttj| jj|d |d ||d || j d	 |   t|trn | j  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
durationMSfailuredriverConnectionIdr!   ) rg   r(   r)   _check_oncer   r   r$   r^   rj   r*   r2   rm   r}   r   re   rc   publish_server_heartbeat_failedr   isEnabledForloggingDEBUGr   r   HEARTBEAT_FAILrD   _topology_idrx   r   r
   rk   ry   r   )rF   r%   r   sdrj   durationr   r"   r"   r#   r|      sD   


zMonitor._check_serverc           	      C  s  | 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tj| jj|j|j|d |d |d |j| _|j| _| |\}}|jsk| j| | j  \}}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   S 1 sw   Y  dS )zfA single attempt to call hello.

        Returns a ServerDescription, or raises an exception.
        Nr   r   )r   r   r   serverConnectionIdr   r   r   )min_round_trip_timer   )	r   r   r   r   r   r   r   r   reply)%r^   rj   r2   r_   connsrm   r}   r   re   rc    publish_server_heartbeat_startedrf   	cancelledrx   checkoutr   r   r   r   r   r   HEARTBEAT_STARTrD   r   idserver_connection_idcancel_contextrg   _check_with_socket	awaitablerk   
add_samplegetr   "publish_server_heartbeat_succeededHEARTBEAT_SUCCESSdocument)	rF   rj   r   r   connresponseround_trip_timeavg_rttmin_rttr"   r"   r#   r   #  sb   
$zMonitor._check_oncer   r   tuple[Hello, float]c                 C  sf   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)r(   r)   more_to_comer   _next_replyrm   performed_handshaker^   r   _hellor`   r\   r*   )rF   r   r%   r   r   r"   r"   r#   r   `  s    zMonitor._check_with_socket)rU   r   r,   r   rV   r   rW   r   rP   )r   r   )r   r   r   r   )rQ   rR   rS   rH   rr   rt   r<   rM   rB   rx   r3   r|   r   r   __classcell__r"   r"   rn   r#   rT      s    
(

	




*
'=rT   c                      s2   e Zd Zd fddZdd	d
ZdddZ  ZS )
SrvMonitorr,   r   rW   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)r[   rH   r   MIN_SRV_RESCAN_INTERVALr\   r`   _seeds	_seedlistr   fqdnr.   _fqdnr(   r)   _startup_time)rF   r,   rW   rn   r"   r#   rH   y  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   rD   on_srv_updater   rB   )rF   seedlistr"   r"   r#   r3     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   r`   pool_optionsconnect_timeoutsrv_service_nameget_hosts_and_min_ttllenr   rO   r?   update_intervalr'   r   r   )rF   resolverr   ttlr"   r"   r#   r     s    zSrvMonitor._get_seedlist)r,   r   rW   r   rP   )r   r   )rQ   rR   rS   rH   r3   r   r   r"   r"   rn   r#   r   x  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 )rh   r,   r   rW   r   rV   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)r[   rH   r\   r   r]   r_   r   _moving_averager   _moving_minr   _lock)rF   r,   rW   rV   rn   r"   r#   rH     s   z_RttMonitor.__init__r   r   c                 C  s   |    | j  d S r:   )r<   r_   ry   rK   r"   r"   r#   rB     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   )rF   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   rK   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   ry   r   rK   r"   r"   r#   ry     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   rB   r   r_   ry   )rF   rttr"   r"   r#   r3     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)	r_   r   r?   rs   r   r(   r)   hellor*   )rF   r   r%   r"   r"   r#   r     s   $z_RttMonitor._ping)r,   r   rW   r   rV   r   rP   )r   r&   r   r   )r   r   )r   r&   )rQ   rR   rS   rH   rB   r   r   ry   r3   r   r   r"   r"   rn   r#   rh     s    




rh   r4   c                 C  s   t | t}t| d S r:   )r@   rA   _unregister	_MONITORSadd)r4   rA   r"   r"   r#   rE     s   rE   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<   )monitorsrA   r4   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&   )r4   r+   r   r   )r   r   r   r   rP   )<__doc__
__future__r   rv   atexitr   r(   r@   typingr   r   r   pymongor   r   pymongo._csotr   pymongo.errorsr	   r
   pymongo.hellor   pymongo.lockr   pymongo.loggerr   r   r   pymongo.periodic_executorr   pymongo.pool_optionsr   pymongo.read_preferencesr   pymongo.server_descriptionr    pymongo.synchronous.srv_resolverr   pymongo.synchronous.poolr   r   r   pymongo.synchronous.settingsr   pymongo.synchronous.topologyr   _IS_SYNCr$   r*   r+   rT   r   rh   setr   rE   r   r   r   registerr"   r"   r"   r#   <module>   sN   

	> y<C




