@@ -44,6 +44,9 @@ def __init__(
4444 self ._pool  =  pool 
4545 self ._settings  =  topology_settings 
4646 self ._avg_round_trip_time  =  MovingAverage ()
47+  self ._listeners  =  self ._settings ._pool_options .event_listeners 
48+  pub  =  self ._listeners  is  not   None 
49+  self ._publish  =  pub  and  self ._listeners .enabled_for_server_heartbeat 
4750
4851 # We strongly reference the executor and it weakly references us via 
4952 # this closure. When the monitor is freed, stop the executor soon. 
@@ -61,7 +64,7 @@ def target():
6164 name = "pymongo_server_monitor_thread" )
6265
6366 self ._executor  =  executor 
64-   
67+ 
6568 # Avoid cycles. When self or topology is freed, stop executor soon. 
6669 self_ref  =  weakref .ref (self , executor .close )
6770 self ._topology  =  weakref .proxy (topology , executor .close )
@@ -110,24 +113,34 @@ def _check_with_retry(self):
110113 address  =  self ._server_description .address 
111114 retry  =  self ._server_description .server_type  !=  SERVER_TYPE .Unknown 
112115
116+  start  =  _time ()
113117 try :
114118 return  self ._check_once ()
115119 except  ReferenceError :
116120 raise 
117121 except  Exception  as  error :
122+  error_time  =  _time () -  start 
118123 self ._topology .reset_pool (address )
119124 default  =  ServerDescription (address , error = error )
120125 if  not  retry :
126+  if  self ._publish :
127+  self ._listeners .publish_server_heartbeat_failed (
128+  address , error_time , error )
121129 self ._avg_round_trip_time .reset ()
122130 # Server type defaults to Unknown. 
123131 return  default 
124132
125133 # Try a second and final time. If it fails return original error. 
134+  start  =  _time ()
126135 try :
127136 return  self ._check_once ()
128137 except  ReferenceError :
129138 raise 
130-  except  Exception :
139+  except  Exception  as  error :
140+  error_time  =  _time () -  start 
141+  if  self ._publish :
142+  self ._listeners .publish_server_heartbeat_failed (
143+  address , error_time , error )
131144 self ._avg_round_trip_time .reset ()
132145 return  default 
133146
@@ -136,13 +149,19 @@ def _check_once(self):
136149
137150 Returns a ServerDescription, or raises an exception. 
138151 """ 
152+  address  =  self ._server_description .address 
153+  if  self ._publish :
154+  self ._listeners .publish_server_heartbeat_started (address )
139155 with  self ._pool .get_socket ({}) as  sock_info :
140156 response , round_trip_time  =  self ._check_with_socket (sock_info )
141157 self ._avg_round_trip_time .add_sample (round_trip_time )
142158 sd  =  ServerDescription (
143-  address = self . _server_description . address ,
159+  address = address ,
144160 ismaster = response ,
145161 round_trip_time = self ._avg_round_trip_time .get ())
162+  if  self ._publish :
163+  self ._listeners .publish_server_heartbeat_succeeded (
164+  address , round_trip_time , response )
146165
147166 return  sd 
148167
0 commit comments