@@ -4,6 +4,7 @@ use std::{
44} ;
55
66use bson:: { bson, doc} ;
7+ use lazy_static:: lazy_static;
78use time:: PreciseTime ;
89
910use super :: {
@@ -19,6 +20,11 @@ use crate::{
1920
2021const DEFAULT_HEARTBEAT_FREQUENCY : Duration = Duration :: from_secs ( 10 ) ;
2122
23+ lazy_static ! {
24+ // Unfortunately, the `time` crate has not yet updated to make the `Duration` constructors `const`, so we have to use lazy_static.
25+ pub ( crate ) static ref MIN_HEARTBEAT_FREQUENCY : time:: Duration = time:: Duration :: milliseconds( 500 ) ;
26+ }
27+
2228/// Starts a monitoring thread associated with a given Server. A weak reference is used to ensure
2329/// that the monitoring thread doesn't keep the server alive after it's been removed from the
2430/// topology or the client has been dropped.
@@ -37,9 +43,28 @@ pub(super) fn monitor_server(
3743 None => return ,
3844 } ;
3945
40- match server. upgrade ( ) {
46+ let last_check = PreciseTime :: now ( ) ;
47+
48+ let timed_out = match server. upgrade ( ) {
4149 Some ( server) => server. wait_timeout ( heartbeat_frequency) ,
4250 None => return ,
51+ } ;
52+
53+ if !timed_out {
54+ let duration_since_last_check = last_check. to ( PreciseTime :: now ( ) ) ;
55+
56+ if duration_since_last_check < * MIN_HEARTBEAT_FREQUENCY {
57+ let remaining_time = * MIN_HEARTBEAT_FREQUENCY - duration_since_last_check;
58+
59+ // Since MIN_HEARTBEAT_FREQUENCY is 500 and `duration_since_last_check` is less
60+ // than it but still positive, we can be sure that the time::Duration can be
61+ // successfully converted to a std::time::Duration. However, in the case of some
62+ // bug causing this not to be true, rather than panicking the monitoring thread,
63+ // we instead just don't sleep and proceed to checking the server a bit early.
64+ if let Ok ( remaining_time) = remaining_time. to_std ( ) {
65+ std:: thread:: sleep ( remaining_time) ;
66+ }
67+ }
4368 }
4469 }
4570 } ) ;
0 commit comments