3
]ð]z$  ã               @   s˜   d Z ddlZddl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 G d
d„ deƒZG dd„ deƒZG dd„ deƒZdS )z9Class to monitor a MongoDB server on a background thread.é    N)ÚcommonÚperiodic_executor)ÚOperationFailure)Útime)ÚMovingAverage)ÚServerDescription)ÚSERVER_TYPE)Ú_SrvResolverc               @   s6   e Zd Zdd„ Zdd„ Zdd„ Zddd	„Zd
d„ ZdS )ÚMonitorBasec             O   s   t ‚dS )z+Override this method to create an executor.N)ÚNotImplementedError)ÚselfÚargsÚkwargs© r   ú2/tmp/pip-build-20mum3z4/pymongo/pymongo/monitor.pyÚ__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)Ú	_executorÚopen)r   r   r   r   r   !   s    zMonitorBase.openc             C   s   | j jƒ  dS )zWClose and stop monitoring.

        open() restarts the monitor after closing.
        N)r   Úclose)r   r   r   r   r   (   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   /   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_check3   s    zMonitorBase.request_check)N)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r   r   r   r   r
      s
   
r
   c                   sD   e Zd Zdd„ Z‡ fdd„Zdd„ Zdd„ Zd	d
„ Zdd„ Z‡  Z	S )ÚMonitorc                sŠ   || _ || _|| _tƒ | _| jjj| _| jdk	}|o:| jj| _	‡ fdd„}t
j| jjtj|dd�}|| _tj| |jƒ‰ tj||jƒ| _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.
        Nc                 s    ˆ ƒ } | d krdS t j| ƒ dS )NFT)r   Ú_run)Úmonitor)Úself_refr   r   ÚtargetQ   s
    
z Monitor.__init__.<locals>.targetZpymongo_server_monitor_thread)ÚintervalÚmin_intervalr   Úname)Ú_server_descriptionÚ_poolÚ	_settingsr   Ú_avg_round_trip_timeZ_pool_optionsZevent_listenersÚ
_listenersZenabled_for_server_heartbeatÚ_publishr   ÚPeriodicExecutorÚheartbeat_frequencyr   ZMIN_HEARTBEAT_INTERVALr   ÚweakrefÚrefr   ÚproxyÚ	_topology)r   Zserver_descriptionÚtopologyÚpoolÚtopology_settingsZpubr   Úexecutorr   )r   r   r   9   s     
zMonitor.__init__c                s   t t| ƒjƒ  | jjƒ  d S )N)Úsuperr   r   r$   Úreset)r   )Ú	__class__r   r   r   d   s    zMonitor.closec             C   s>   y| j ƒ | _| jj| jƒ W n tk
r8   | jƒ  Y nX d S )N)Ú_check_with_retryr#   r.   Z	on_changeÚReferenceErrorr   )r   r   r   r   r   k   s
    
zMonitor._runc             C   s$  | j j}d}| j jtjkrd}tƒ }y| jƒ S  tk
rB   ‚ Y nÞ tk
�r } zÀtƒ | }| j	rt| j
j|||ƒ | jj|ƒ t||d�}|sž| jjƒ  |S tƒ }y| jƒ S  tk
rÂ   ‚ Y nL tk
�r } z.tƒ | }| j	rô| j
j|||ƒ | jjƒ  |S d}~X nX W Y dd}~X nX dS )ziCall ismaster once or twice. Reset server's pool on error.

        Returns a ServerDescription.
        TF)ÚerrorN)r#   ÚaddressZserver_typer   ÚUnknownÚ_timeÚ_check_oncer7   Ú	Exceptionr(   r'   Zpublish_server_heartbeat_failedr.   Z
reset_poolr   r&   r4   )r   r9   ÚretryÚstartr8   Z
error_timeÚdefaultr   r   r   r6   s   s>    





zMonitor._check_with_retryc             C   sz   | j j}| jr| jj|ƒ | jji ƒ�J}| j|ƒ\}}| jj	|ƒ t
||| jjƒ d�}| jrl| jj|||ƒ |S Q R X dS )ziA single attempt to call ismaster.

        Returns a ServerDescription, or raises an exception.
        )r9   ÚismasterÚround_trip_timeN)r#   r9   r(   r'   Z publish_server_heartbeat_startedr$   Z
get_socketÚ_check_with_socketr&   Z
add_sampler   ÚgetZ"publish_server_heartbeat_succeeded)r   r9   Ú	sock_infoÚresponserB   Úsdr   r   r   r<       s    
zMonitor._check_oncec             C   sf   t ƒ }y"|j| jjj| jjƒ ƒt ƒ | fS  tk
r` } z| jj|j	j
dƒƒ ‚ W Y dd}~X nX dS )zfReturn (IsMaster, round_trip_time).

        Can raise ConnectionFailure or OperationFailure.
        z$clusterTimeN)r;   rA   r$   ÚoptsÚmetadatar.   Zmax_cluster_timer   Zreceive_cluster_timeÚdetailsrD   )r   rE   r?   Úexcr   r   r   rC   µ   s    
zMonitor._check_with_socket)
r   r   r   r   r   r   r6   r<   rC   Ú__classcell__r   r   )r5   r   r   8   s   +-r   c               @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )Ú
SrvMonitorc                sf   || _ | j j| _| j j| _‡ fdd„}tjtj| j j	|dd�}|| _
tj| |jƒ‰ tj||jƒ| _dS )z—Class to poll SRV records on a background thread.

        Pass a Topology and a TopologySettings.

        The Topology is weakly referenced.
        c                 s    ˆ ƒ } | d krdS t j| ƒ dS )NFT)rM   r   )r   )r   r   r   r   Ô   s
    
z#SrvMonitor.__init__.<locals>.targetZpymongo_srv_polling_thread)r    r!   r   r"   N)r%   Z_seedsÚ	_seedlistZfqdnÚ_fqdnr   r)   r   ÚMIN_SRV_RESCAN_INTERVALr*   r   r+   r,   r   r-   r.   )r   r/   r1   r   r2   r   )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_seedlistrN   r.   Zon_srv_updater7   r   )r   Úseedlistr   r   r   r   ç   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	   rO   Zget_hosts_and_min_ttlÚlenr=   r   r   Zupdate_intervalÚmaxr   rP   )r   rR   Zttlr   r   r   rQ   ñ   s    zSrvMonitor._get_seedlistN)r   r   r   r   r   rQ   r   r   r   r   rM   Æ   s    
rM   )Ú__doc__r+   Zpymongor   r   Zpymongo.errorsr   Zpymongo.monotonicr   r;   Zpymongo.read_preferencesr   Zpymongo.server_descriptionr   Zpymongo.server_typer   Zpymongo.srv_resolverr	   Úobjectr
   r   rM   r   r   r   r   Ú<module>   s    