@@ -16,6 +16,7 @@ use super::{
16
16
TopologyWatcher ,
17
17
} ;
18
18
use crate :: {
19
+ client:: options:: ServerMonitoringMode ,
19
20
cmap:: { establish:: ConnectionEstablisher , Connection } ,
20
21
error:: { Error , Result } ,
21
22
event:: sdam:: {
@@ -48,11 +49,15 @@ pub(crate) struct Monitor {
48
49
sdam_event_emitter : Option < SdamEventEmitter > ,
49
50
client_options : ClientOptions ,
50
51
52
+ /// Whether this monitor is allowed to use the streaming protocol.
53
+ allow_streaming : bool ,
54
+
51
55
/// The most recent topology version returned by the server in a hello response.
52
- /// If some, indicates that this monitor should use the streaming protocol. If none, it should
53
- /// use the polling protocol.
54
56
topology_version : Option < TopologyVersion > ,
55
57
58
+ /// The RTT monitor; once it's started this is None.
59
+ pending_rtt_monitor : Option < RttMonitor > ,
60
+
56
61
/// Handle to the RTT monitor, used to get the latest known round trip time for a given server
57
62
/// and to reset the RTT when the monitor disconnects from the server.
58
63
rtt_monitor_handle : RttMonitorHandle ,
@@ -79,21 +84,31 @@ impl Monitor {
79
84
connection_establisher. clone ( ) ,
80
85
client_options. clone ( ) ,
81
86
) ;
87
+ let allow_streaming = match client_options
88
+ . server_monitoring_mode
89
+ . clone ( )
90
+ . unwrap_or ( ServerMonitoringMode :: Auto )
91
+ {
92
+ ServerMonitoringMode :: Stream => true ,
93
+ ServerMonitoringMode :: Poll => false ,
94
+ ServerMonitoringMode :: Auto => !crate :: cmap:: is_faas ( ) ,
95
+ } ;
82
96
let monitor = Self {
83
97
address,
84
98
client_options,
85
99
connection_establisher,
86
100
topology_updater,
87
101
topology_watcher,
88
102
sdam_event_emitter,
103
+ pending_rtt_monitor : Some ( rtt_monitor) ,
89
104
rtt_monitor_handle,
90
105
request_receiver : manager_receiver,
91
106
connection : None ,
107
+ allow_streaming,
92
108
topology_version : None ,
93
109
} ;
94
110
95
111
runtime:: execute ( monitor. execute ( ) ) ;
96
- runtime:: execute ( rtt_monitor. execute ( ) ) ;
97
112
}
98
113
99
114
async fn execute ( mut self ) {
@@ -102,13 +117,19 @@ impl Monitor {
102
117
while self . is_alive ( ) {
103
118
let check_succeeded = self . check_server ( ) . await ;
104
119
120
+ if self . topology_version . is_some ( ) && self . allow_streaming {
121
+ if let Some ( rtt_monitor) = self . pending_rtt_monitor . take ( ) {
122
+ runtime:: execute ( rtt_monitor. execute ( ) ) ;
123
+ }
124
+ }
125
+
105
126
// In the streaming protocol, we read from the socket continuously
106
127
// rather than polling at specific intervals, unless the most recent check
107
128
// failed.
108
129
//
109
130
// We only go to sleep when using the polling protocol (i.e. server never returned a
110
131
// topologyVersion) or when the most recent check failed.
111
- if self . topology_version . is_none ( ) || !check_succeeded {
132
+ if self . topology_version . is_none ( ) || !check_succeeded || ! self . allow_streaming {
112
133
self . request_receiver
113
134
. wait_for_check_request (
114
135
self . client_options . min_heartbeat_frequency ( ) ,
@@ -180,7 +201,7 @@ impl Monitor {
180
201
self . emit_event ( || {
181
202
SdamEvent :: ServerHeartbeatStarted ( ServerHeartbeatStartedEvent {
182
203
server_address : self . address . clone ( ) ,
183
- awaited : self . topology_version . is_some ( ) ,
204
+ awaited : self . topology_version . is_some ( ) && self . allow_streaming ,
184
205
driver_connection_id,
185
206
server_connection_id : self . connection . as_ref ( ) . and_then ( |c| c. server_id ) ,
186
207
} )
@@ -213,10 +234,14 @@ impl Monitor {
213
234
} else {
214
235
// If the initial handshake returned a topology version, send it back to the
215
236
// server to begin streaming responses.
216
- let opts = self . topology_version . map ( |tv| AwaitableHelloOptions {
217
- topology_version : tv,
218
- max_await_time : heartbeat_frequency,
219
- } ) ;
237
+ let opts = if self . allow_streaming {
238
+ self . topology_version . map ( |tv| AwaitableHelloOptions {
239
+ topology_version : tv,
240
+ max_await_time : heartbeat_frequency,
241
+ } )
242
+ } else {
243
+ None
244
+ } ;
220
245
221
246
let command = hello_command (
222
247
self . client_options . server_api . as_ref ( ) ,
@@ -266,8 +291,12 @@ impl Monitor {
266
291
} ;
267
292
let duration = start. elapsed ( ) ;
268
293
294
+ let awaited = self . topology_version . is_some ( ) && self . allow_streaming ;
269
295
match result {
270
296
HelloResult :: Ok ( ref r) => {
297
+ if !awaited {
298
+ self . rtt_monitor_handle . add_sample ( duration) ;
299
+ }
271
300
self . emit_event ( || {
272
301
let mut reply = r
273
302
. raw_command_response
@@ -280,7 +309,7 @@ impl Monitor {
280
309
duration,
281
310
reply,
282
311
server_address : self . address . clone ( ) ,
283
- awaited : self . topology_version . is_some ( ) ,
312
+ awaited,
284
313
driver_connection_id,
285
314
server_connection_id : self . connection . as_ref ( ) . and_then ( |c| c. server_id ) ,
286
315
} )
@@ -296,7 +325,7 @@ impl Monitor {
296
325
duration,
297
326
failure : e. clone ( ) ,
298
327
server_address : self . address . clone ( ) ,
299
- awaited : self . topology_version . is_some ( ) ,
328
+ awaited,
300
329
driver_connection_id,
301
330
server_connection_id : self . connection . as_ref ( ) . and_then ( |c| c. server_id ) ,
302
331
} )
0 commit comments