@@ -4,6 +4,7 @@ use std::{
4
4
} ;
5
5
6
6
use bson:: { bson, doc} ;
7
+ use lazy_static:: lazy_static;
7
8
use time:: PreciseTime ;
8
9
9
10
use super :: {
@@ -19,6 +20,11 @@ use crate::{
19
20
20
21
const DEFAULT_HEARTBEAT_FREQUENCY : Duration = Duration :: from_secs ( 10 ) ;
21
22
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
+
22
28
/// Starts a monitoring thread associated with a given Server. A weak reference is used to ensure
23
29
/// that the monitoring thread doesn't keep the server alive after it's been removed from the
24
30
/// topology or the client has been dropped.
@@ -37,9 +43,28 @@ pub(super) fn monitor_server(
37
43
None => return ,
38
44
} ;
39
45
40
- match server. upgrade ( ) {
46
+ let last_check = PreciseTime :: now ( ) ;
47
+
48
+ let timed_out = match server. upgrade ( ) {
41
49
Some ( server) => server. wait_timeout ( heartbeat_frequency) ,
42
50
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
+ }
43
68
}
44
69
}
45
70
} ) ;
0 commit comments