o Sb;@sdZddlZddlZddlZddlZddlmZmZmZddl m Z m Z ddl m Z mZmZddlmZddlmZddlmZdd lmZdd lmZd d ZGd ddeZGdddeZGdddeZGdddeZe Z!ddZ"ddZ#ddZ$ddZ%e&e%dS)z9Class to monitor a MongoDB server on a background thread.N)AnyMappingcast)commonperiodic_executor)NotPrimaryErrorOperationFailure_OperationCancelled)Hello)_shutdown_executors) MovingAverage)ServerDescription) _SrvResolvercCsd|_d|_d|_dS)z'PYTHON-2433 Clear error traceback info.N) __traceback__ __context__ __cause__errorr6/tmp/pip-target-onvjaxws/lib/python/pymongo/monitor.py _sanitize s rc@s>eZdZddZddZddZddZdd d Zd d Zd S) MonitorBasecsZfdd}tj||||d}||_dfdd }t||jt|||_t|dS)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. cs}|dur dS|dS)NFT)_run)monitorZself_refrrtarget0s z$MonitorBase.__init__..target)interval min_intervalrnameNcs}|r |dSdSN gc_safe_close)dummyrrrr_on_topology_gc=s z-MonitorBase.__init__.._on_topology_gcr) rZPeriodicExecutor _executorweakrefrefcloseproxy _topology _register)selftopologyrrrrexecutorr#rrr__init__(s  zMonitorBase.__init__cC|jdS)z[Start monitoring, or restart after a fork. Multiple calls have no effect. N)r$openr+rrrr0IszMonitorBase.opencCr/)zGC safe close.N)r$r'r1rrrr!PzMonitorBase.gc_safe_closecCs |dS)zWClose and stop monitoring. open() restarts the monitor after closing. Nr r1rrrr'Ts zMonitorBase.closeNcCs|j|dS)zWait for the monitor to stop.N)r$join)r+timeoutrrrr3[szMonitorBase.joincCr/)z)If the monitor is sleeping, wake it soon.N)r$Zwaker1rrr request_check_r2zMonitorBase.request_checkr) __name__ __module__ __qualname__r.r0r!r'r3r5rrrrr's!  rcsdeZdZfddZddZddZddZd d Zd d Zd dZ ddZ ddZ ddZ Z S)Monitorcsvtt||d|jtj||_||_||_|jj j |_ |j du}|o&|j j |_ d|_t||||j|_d|_dS)aClass 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. Zpymongo_server_monitor_threadN)superr9r.heartbeat_frequencyrMIN_HEARTBEAT_INTERVAL_server_description_pool _settingsZ _pool_optionsZ_event_listeners _listenersZenabled_for_server_heartbeat_publish_cancel_context _RttMonitorZ_create_pool_for_monitoraddress _rtt_monitorZ heartbeater)r+Zserver_descriptionr,pooltopology_settingsZpub __class__rrr.es&     zMonitor.__init__cCs|j}|r |dSdS)zCancel any concurrent hello check. Note: this is called from a weakref.proxy callback and MUST NOT take any locks. N)rBcancel)r+contextrrr cancel_checks zMonitor.cancel_checkcCs$|j|jjr|jdSdS)z1Start an _RttMonitor that periodically runs ping.N)rEr0r$_stoppedr'r1rrr_start_rtt_monitors zMonitor._start_rtt_monitorcCs |j|j|dSr)r$r'rEr!rLr1rrrr!s   zMonitor.gc_safe_closecCs||j|dSr)r!rEr'_reset_connectionr1rrrr's  z Monitor.closecCs|jdSr)r>resetr1rrrrOr2zMonitor._reset_connectionc Csze|j}z||_Wn)ty4}zt|t|jj|d|_|jr(|jWYd}~WdSd}~ww|j j |j|jj d|jjrQ|jj rQ| |j|jj r`|jrc|jWdSWdSWdStys|YdSw)Nr)Z reset_pool)r= _check_serverr rr rDis_server_type_knownr$Z skip_sleepr)Z on_changertopology_versionrNReferenceErrorr')r+Zprev_sdexcrrrrs:    z Monitor._runc Cst}z)z|WWSttfy-}zttttf|j }|j | dd}~wwt y5ty}}z=t||j}|j}t|}|jr^|joT|j}|j|||||t|trh|jt||dWYd}~Sd}~ww)z^Call hello or read the next streaming response. Returns a ServerDescription. z $clusterTimeNr)time monotonic _check_oncerrrrstrrdetailsr)Zreceive_cluster_timegetrT Exceptionrr=rDrArRrSr@Zpublish_server_heartbeat_failedrO isinstancer rErPr ) r+startrUrZrsdrDdurationZawaitedrrrrQs6      zMonitor._check_servercCs|jj}|jr |j||jr|jjr||j 4}|j |_| |\}}|j s2|j |t|||j }|jrH|j||||j |WdS1sTwYdS)zfA single attempt to call hello. Returns a ServerDescription, or raises an exception. N)r=rDrAr@Z publish_server_heartbeat_startedrB cancelledrOr> get_socketZcancel_context_check_with_socket awaitablerE add_sampler averageZ"publish_server_heartbeat_succeeded)r+rD sock_inforesponseZround_trip_timer_rrrrXs"    $zMonitor._check_oncecCsn|j}t}|jrt|dd}n|jr(|jj r(| ||jj |j j }n| |dd}|t|fS)zcReturn (Hello, round_trip_time). Can raise ConnectionFailure or OperationFailure. T)rdN) r)Zmax_cluster_timerVrWZ more_to_comer Z _next_replyZperformed_handshaker=rSZ_hellor?r;)r+connZ cluster_timer^rhrrrrcs zMonitor._check_with_socket)r6r7r8r.rLrNr!r'rOrrQrXrc __classcell__rrrHrr9ds   %r9cs,eZdZfddZddZddZZS) SrvMonitorcs8tt||dtj|j||_|jj|_|jj |_ dS)zClass to poll SRV records on a background thread. Pass a Topology and a TopologySettings. The Topology is weakly referenced. Zpymongo_srv_polling_threadN) r:rkr.rMIN_SRV_RESCAN_INTERVALr;r?Z_seeds _seedlistZfqdn_fqdn)r+r,rGrHrrr.s  zSrvMonitor.__init__cCsH|}|r"||_z |j|jWdSty!|YdSwdSr) _get_seedlistrmr)Z on_srv_updaterTr')r+seedlistrrrr-s zSrvMonitor._runcCsnzt|j|jjj|jj}|\}}t|dkrtWnty*| YdSw|j t |t j|S)zXPoll SRV records for a seedlist. Returns a list of ServerDescriptions. rN)rrnr?Z pool_optionsconnect_timeoutZsrv_service_nameZget_hosts_and_min_ttllenr\r5r$Zupdate_intervalmaxrrl)r+resolverrpttlrrrro7s    zSrvMonitor._get_seedlist)r6r7r8r.rrorjrrrHrrks  rkcsLeZdZfddZddZddZddZd d Zd d Zd dZ Z S)rCcs6tt||d|jtj||_t|_t |_ dS)z\Maintain round trip times for a server. The Topology is weakly referenced. Zpymongo_server_rtt_threadN) r:rCr.r;rr<r>r _moving_average threadingLock_lock)r+r,rGrFrHrrr.Ss z_RttMonitor.__init__cCs||jdSr)r!r>rPr1rrrr'csz_RttMonitor.closecCs8|j|j|WddS1swYdS)zAdd a RTT sample.N)ryrvre)r+samplerrrreis"z_RttMonitor.add_samplecC4|j |jWdS1swYdS)z6Get the calculated average, or None if no samples yet.N)ryrvr[r1rrrrfn$z_RttMonitor.averagecCr{)zReset the average RTT.N)ryrvrPr1rrrrPsr|z_RttMonitor.resetcCsRz |}||WdSty|YdSty(|jYdSwr)_pingrerTr'r\r>rP)r+Zrttrrrrxs  z_RttMonitor._runcCsZ|j}|jjrtdt}|t|WdS1s&wYdS)z)Run a "hello" command and return the RTT.z_RttMonitor closedN)r>rbr$rMr\rVrWZhello)r+rgr^rrrr}s  $z_RttMonitor._ping) r6r7r8r.r'rerfrPrr}rjrrrHrrCRs  rCcCst|t}t|dSr)r%r& _unregister _MONITORSadd)rr&rrrr*s r*cCst|dSr)rremove)Z monitor_refrrrr~sr~cCs8tdurdStt}|D] }|}|r|q d}dSr)rlistr!)Zmonitorsr&rrrr_shutdown_monitorssrcCs$t}|r|t}|r|dSdSr)rr )shutdownrrr_shutdown_resourcess r)'__doc__atexitrwrVr%typingrrrZpymongorrZpymongo.errorsrrr Z pymongo.hellor Zpymongo.periodic_executorr Zpymongo.read_preferencesr Zpymongo.server_descriptionr Zpymongo.srv_resolverrrobjectrr9rkrCsetrr*r~rrregisterrrrrs2     =87@