3
O6b/;                 @   s  d Z ddlZddlZddlZddlmZ ddlmZ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 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e  Z!dd Z"dd Z#dd Z$dd Z%ej&e% dS )z9Class to monitor a MongoDB server on a background thread.    N)PY3)commonperiodic_executor)NotPrimaryErrorOperationFailure_OperationCancelled)IsMaster)time)_shutdown_executors)MovingAverage)ServerDescription)_SrvResolverc             C   s   t rd| _d| _d| _dS )z'PYTHON-2433 Clear error traceback info.N)r   __traceback____context__	__cause__)error r   N/var/www/html/sandeepIITI/myenv/lib/python3.6/site-packages/pymongo/monitor.py	_sanitize#   s    r   c               @   s>   e Zd Zdd Zdd Zdd Zdd Zdd
dZdd Zd	S )MonitorBasec                sZ    fdd}t j||||d}|| _d fdd	}tj| |j tj||| _t|  dS )zBase class to do periodic work on a background thread.

        The the background thread is signaled to stop when the Topology or
        this instance is freed.
        c                 s     } | d krdS | j   dS )NFT)_run)monitor)self_refr   r   target4   s
    z$MonitorBase.__init__.<locals>.target)intervalmin_intervalr   nameNc                s     }|r|j   d S )N)gc_safe_close)dummyr   )r   r   r   _on_topology_gcC   s    z-MonitorBase.__init__.<locals>._on_topology_gc)N)	r   ZPeriodicExecutor	_executorweakrefrefcloseproxy	_topology	_register)selftopologyr   r   r   r   executorr   r   )r   r   __init__,   s    zMonitorBase.__init__c             C   s   | j j  dS )z[Start monitoring, or restart after a fork.

        Multiple calls have no effect.
        N)r    open)r'   r   r   r   r+   O   s    zMonitorBase.openc             C   s   | j j  dS )zGC safe close.N)r    r#   )r'   r   r   r   r   V   s    zMonitorBase.gc_safe_closec             C   s   | j   dS )zWClose and stop monitoring.

        open() restarts the monitor after closing.
        N)r   )r'   r   r   r   r#   Z   s    zMonitorBase.closeNc             C   s   | j j| dS )zWait for the monitor to stop.N)r    join)r'   timeoutr   r   r   r,   a   s    zMonitorBase.joinc             C   s   | j j  dS )z)If the monitor is sleeping, wake it soon.N)r    Zwake)r'   r   r   r   request_checke   s    zMonitorBase.request_check)N)	__name__
__module____qualname__r*   r+   r   r#   r,   r.   r   r   r   r   r   +   s   #
r   c                   sd   e Zd Z fddZdd Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd Zdd Z  ZS )Monitorc                sv   t t| j|d|jtj || _|| _|| _| jj	j
| _| jdk	}|oL| jj| _d| _t|||j|j| _d| _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_threadN)superr2   r*   heartbeat_frequencyr   MIN_HEARTBEAT_INTERVAL_server_description_pool	_settingsZ_pool_optionsZevent_listeners
_listenersZenabled_for_server_heartbeat_publish_cancel_context_RttMonitorZ_create_pool_for_monitoraddress_rtt_monitorZheartbeater)r'   Zserver_descriptionr(   pooltopology_settingsZpub)	__class__r   r   r*   k   s     

zMonitor.__init__c             C   s   | j }|r|j  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)r'   contextr   r   r   cancel_check   s    zMonitor.cancel_checkc             C   s    | j j  | jjr| j j  dS )z1Start an _RttMonitor that periodically runs ping.N)r>   r+   r    _stoppedr#   )r'   r   r   r   _start_rtt_monitor   s    
zMonitor._start_rtt_monitorc             C   s    | j j  | jj  | j  d S )N)r    r#   r>   r   rD   )r'   r   r   r   r      s    

zMonitor.gc_safe_closec             C   s   | j   | jj  | j  d S )N)r   r>   r#   _reset_connection)r'   r   r   r   r#      s    
zMonitor.closec             C   s   | j j  d S )N)r7   reset)r'   r   r   r   rG      s    zMonitor._reset_connectionc             C   s   y| j }y| j | _ W nJ tk
r` } z.t| t| j j|d| _ |jrR| jj  d S d }~X nX | j	j
| j | j jd | j jr| j jr| j  | jj  | j jr|jr| jj  W n tk
r   | j  Y nX d S )N)r   )Z
reset_pool)r6   _check_serverr   r   r   r=   is_server_type_knownr    Z
skip_sleepr%   Z	on_changer   topology_versionrF   ReferenceErrorr#   )r'   Zprev_sdexcr   r   r   r      s*    


zMonitor._runc             C   s   t  }yJy| j S  ttfk
rL } z| jj|jjd  W Y dd}~X nX W n tk
rf    Y n t	k
r } zlt
| | j}|j}t  | }| jr|jo|j}| jj|||| | j  t|tr̂ | jj  t||dS d}~X nX dS )z^Call hello or read the next streaming response.

        Returns a ServerDescription.
        z$clusterTimeN)r   )_time_check_oncer   r   r%   Zreceive_cluster_timedetailsgetrL   	Exceptionr   r6   r=   r:   rJ   rK   r9   Zpublish_server_heartbeat_failedrG   
isinstancer   r>   rH   r   )r'   startrM   r   sdr=   durationZawaitedr   r   r   rI      s0    


zMonitor._check_serverc             C   s   | j j}| jr| jj| | jr0| jjr0| j  | jj	i Z}|j
| _| j|\}}|jsf| jj| t||| jj }| jr| jj||||j |S Q R X dS )zfA single attempt to call hello.

        Returns a ServerDescription, or raises an exception.
        N)r6   r=   r:   r9   Z publish_server_heartbeat_startedr;   	cancelledrG   r7   
get_socketZcancel_context_check_with_socket	awaitabler>   
add_sampler   averageZ"publish_server_heartbeat_succeeded)r'   r=   	sock_inforesponseZround_trip_timerU   r   r   r   rO      s     zMonitor._check_oncec             C   sn   | j j }t }|jr(t|j dd}n8|jrP| jjrP|j	|| jj| j
jd}n|j	|ddd}|t | fS )zcReturn (Hello, round_trip_time).

        Can raise ConnectionFailure or OperationFailure.
        T)rZ   N)r%   Zmax_cluster_timerN   Zmore_to_comer   Z_next_replyZperformed_handshaker6   rK   Z_hellor8   r4   )r'   connZcluster_timerT   r^   r   r   r   rY   	  s    
zMonitor._check_with_socket)r/   r0   r1   r*   rD   rF   r   r#   rG   r   rI   rO   rY   __classcell__r   r   )rA   r   r2   j   s   	! r2   c                   s,   e Zd Z fddZdd Zdd Z  ZS )
SrvMonitorc                s8   t t| j|dtj|j || _| jj| _| jj	| _
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)r3   ra   r*   r   MIN_SRV_RESCAN_INTERVALr4   r8   Z_seeds	_seedlistZfqdn_fqdn)r'   r(   r@   )rA   r   r   r*   "  s    

zSrvMonitor.__init__c             C   sF   | j  }|rB|| _y| jj| j W n tk
r@   | j  Y nX d S )N)_get_seedlistrc   r%   Zon_srv_updaterL   r#   )r'   seedlistr   r   r   r   2  s    zSrvMonitor._runc             C   s`   y&t | jj \}}t|dkr$tW n tk
rB   | j  dS X | jjt|t	j
 |S dS )zXPoll SRV records for a seedlist.

        Returns a list of ServerDescriptions.
        r   N)r   rd   Zget_hosts_and_min_ttllenrR   r.   r    Zupdate_intervalmaxr   rb   )r'   rf   Zttlr   r   r   re   <  s    zSrvMonitor._get_seedlist)r/   r0   r1   r*   r   re   r`   r   r   )rA   r   ra   !  s   
ra   c                   sL   e Zd Z fddZdd Zdd Zdd Zd	d
 Zdd Zdd Z	  Z
S )r<   c                s6   t t| j|d|jtj || _t | _t	j
 | _dS )z\Maintain round trip times for a server.

        The Topology is weakly referenced.
        Zpymongo_server_rtt_threadN)r3   r<   r*   r4   r   r5   r7   r   _moving_average	threadingLock_lock)r'   r(   r@   r?   )rA   r   r   r*   T  s    
z_RttMonitor.__init__c             C   s   | j   | jj  d S )N)r   r7   rH   )r'   r   r   r   r#   c  s    z_RttMonitor.closec          	   C   s"   | j  | jj| W dQ R X dS )zAdd a RTT sample.N)rl   ri   r[   )r'   sampler   r   r   r[   i  s    z_RttMonitor.add_samplec          	   C   s   | j  | jj S Q R X dS )z6Get the calculated average, or None if no samples yet.N)rl   ri   rQ   )r'   r   r   r   r\   n  s    z_RttMonitor.averagec          	   C   s   | j  | jj S Q R X dS )zReset the average RTT.N)rl   ri   rH   )r'   r   r   r   rH   s  s    z_RttMonitor.resetc             C   sT   y| j  }| j| W n8 tk
r2   | j  Y n tk
rN   | jj  Y nX d S )N)_pingr[   rL   r#   rR   r7   rH   )r'   Zrttr   r   r   r   x  s    z_RttMonitor._runc          	   C   s@   | j ji *}| jjrtdt }|j  t | S Q R X dS )z)Run a "hello" command and return the RTT.z_RttMonitor closedN)r7   rX   r    rE   rR   rN   Zhello)r'   r]   rT   r   r   r   rn     s    z_RttMonitor._ping)r/   r0   r1   r*   r#   r[   r\   rH   r   rn   r`   r   r   )rA   r   r<   S  s   r<   c             C   s   t j| t}tj| d S )N)r!   r"   _unregister	_MONITORSadd)r   r"   r   r   r   r&     s    r&   c             C   s   t j|  d S )N)rp   remove)Zmonitor_refr   r   r   ro     s    ro   c              C   s<   t d krd S tt } x| D ]}| }|r|j  qW d }d S )N)rp   listr   )Zmonitorsr"   r   r   r   r   _shutdown_monitors  s    
rt   c              C   s    t } | r|   t} | r|   d S )N)rt   r
   )shutdownr   r   r   _shutdown_resources  s    rv   )'__doc__atexitrj   r!   Zbson.py3compatr   Zpymongor   r   Zpymongo.errorsr   r   r   Zpymongo.ismasterr   Zpymongo.monotonicr	   rN   Zpymongo.periodic_executorr
   Zpymongo.read_preferencesr   Zpymongo.server_descriptionr   Zpymongo.srv_resolverr   r   objectr   r2   ra   r<   setrp   r&   ro   rt   rv   registerr   r   r   r   <module>   s0   ? 82?
