Skip to content

Commit 135c9f0

Browse files
authored
RUST-1707 Add durations to connection pool events (mongodb#976)
1 parent 11a23ba commit 135c9f0

File tree

10 files changed

+83
-21
lines changed

10 files changed

+83
-21
lines changed

src/cmap.rs

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ pub(crate) mod options;
99
mod status;
1010
mod worker;
1111

12+
use std::time::Instant;
13+
1214
use derivative::Derivative;
1315

1416
pub use self::conn::ConnectionInfo;
@@ -119,6 +121,7 @@ impl ConnectionPool {
119121
/// front of the wait queue, and then will block again if no available connections are in the
120122
/// pool and the total number of connections is not less than the max pool size.
121123
pub(crate) async fn check_out(&self) -> Result<Connection> {
124+
let time_started = Instant::now();
122125
self.event_emitter.emit_event(|| {
123126
ConnectionCheckoutStartedEvent {
124127
address: self.address.clone(),
@@ -142,25 +145,17 @@ impl ConnectionPool {
142145
match conn {
143146
Ok(ref conn) => {
144147
self.event_emitter
145-
.emit_event(|| conn.checked_out_event().into());
146-
}
147-
#[cfg(feature = "tracing-unstable")]
148-
Err(ref err) => {
149-
self.event_emitter.emit_event(|| {
150-
ConnectionCheckoutFailedEvent {
151-
address: self.address.clone(),
152-
reason: ConnectionCheckoutFailedReason::ConnectionError,
153-
error: Some(err.clone()),
154-
}
155-
.into()
156-
});
148+
.emit_event(|| conn.checked_out_event(time_started).into());
157149
}
158-
#[cfg(not(feature = "tracing-unstable"))]
159-
Err(_) => {
150+
151+
Err(ref _err) => {
160152
self.event_emitter.emit_event(|| {
161153
ConnectionCheckoutFailedEvent {
162154
address: self.address.clone(),
163155
reason: ConnectionCheckoutFailedReason::ConnectionError,
156+
#[cfg(feature = "tracing-unstable")]
157+
error: Some(_err.clone()),
158+
duration: Instant::now() - time_started,
164159
}
165160
.into()
166161
});

src/cmap/conn.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ pub(crate) struct Connection {
7474

7575
pub(crate) generation: ConnectionGeneration,
7676

77+
pub(crate) time_created: Instant,
78+
7779
/// The cached StreamDescription from the connection's handshake.
7880
pub(super) stream_description: Option<StreamDescription>,
7981

@@ -127,11 +129,13 @@ impl Connection {
127129
stream: AsyncStream,
128130
id: u32,
129131
generation: ConnectionGeneration,
132+
time_created: Instant,
130133
) -> Self {
131134
Self {
132135
id,
133136
server_id: None,
134137
generation,
138+
time_created,
135139
pool_manager: None,
136140
command_executing: false,
137141
ready_and_available_time: None,
@@ -159,6 +163,7 @@ impl Connection {
159163
stream,
160164
pending_connection.id,
161165
generation,
166+
pending_connection.time_created,
162167
);
163168
conn.event_emitter = Some(pending_connection.event_emitter);
164169
conn
@@ -167,7 +172,13 @@ impl Connection {
167172
/// Create a connection intended for monitoring purposes.
168173
/// TODO: RUST-1454 Rename this to just `new`, drop the pooling-specific data.
169174
pub(crate) fn new_monitoring(address: ServerAddress, stream: AsyncStream, id: u32) -> Self {
170-
Self::new(address, stream, id, ConnectionGeneration::Monitoring)
175+
Self::new(
176+
address,
177+
stream,
178+
id,
179+
ConnectionGeneration::Monitoring,
180+
Instant::now(),
181+
)
171182
}
172183

173184
pub(crate) fn info(&self) -> ConnectionInfo {
@@ -226,10 +237,11 @@ impl Connection {
226237
}
227238

228239
/// Helper to create a `ConnectionCheckedOutEvent` for the connection.
229-
pub(super) fn checked_out_event(&self) -> ConnectionCheckedOutEvent {
240+
pub(super) fn checked_out_event(&self, time_started: Instant) -> ConnectionCheckedOutEvent {
230241
ConnectionCheckedOutEvent {
231242
address: self.address.clone(),
232243
connection_id: self.id,
244+
duration: Instant::now() - time_started,
233245
}
234246
}
235247

@@ -246,6 +258,7 @@ impl Connection {
246258
ConnectionReadyEvent {
247259
address: self.address.clone(),
248260
connection_id: self.id,
261+
duration: Instant::now() - self.time_created,
249262
}
250263
}
251264

@@ -422,6 +435,7 @@ impl Connection {
422435
server_id: self.server_id,
423436
address: self.address.clone(),
424437
generation: self.generation,
438+
time_created: self.time_created,
425439
stream: std::mem::replace(&mut self.stream, BufStream::new(AsyncStream::Null)),
426440
event_emitter: self.event_emitter.take(),
427441
stream_description: self.stream_description.take(),
@@ -599,6 +613,7 @@ pub(crate) struct PendingConnection {
599613
pub(crate) address: ServerAddress,
600614
pub(crate) generation: PoolGeneration,
601615
pub(crate) event_emitter: CmapEventEmitter,
616+
pub(crate) time_created: Instant,
602617
}
603618

604619
impl PendingConnection {

src/cmap/test/event.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use std::sync::{Arc, RwLock};
1+
use std::{
2+
sync::{Arc, RwLock},
3+
time::Duration,
4+
};
25

36
use serde::{de::Unexpected, Deserialize, Deserializer, Serialize};
47

@@ -268,5 +271,6 @@ where
268271
reason,
269272
#[cfg(feature = "tracing-unstable")]
270273
error: None,
274+
duration: Duration::ZERO,
271275
})
272276
}

src/cmap/worker.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ use crate::{
3838

3939
use std::{
4040
collections::{HashMap, VecDeque},
41-
time::Duration,
41+
time::{Duration, Instant},
4242
};
4343

4444
const DEFAULT_MAX_CONNECTING: u32 = 2;
@@ -468,6 +468,7 @@ impl ConnectionPoolWorker {
468468
address: self.address.clone(),
469469
generation: self.generation.clone(),
470470
event_emitter: self.event_emitter.clone(),
471+
time_created: Instant::now(),
471472
};
472473
self.next_connection_id += 1;
473474
self.event_emitter

src/event/cmap.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,10 @@ pub struct ConnectionReadyEvent {
135135
/// to identify other events related to this connection.
136136
#[serde(default = "default_connection_id")]
137137
pub connection_id: u32,
138+
139+
/// The time it took to establish the connection.
140+
#[serde(default = "Duration::default")]
141+
pub duration: Duration,
138142
}
139143

140144
/// Event emitted when a connection is closed.
@@ -216,6 +220,10 @@ pub struct ConnectionCheckoutFailedEvent {
216220
#[serde(skip)]
217221
#[derivative(PartialEq = "ignore")]
218222
pub(crate) error: Option<crate::error::Error>,
223+
224+
/// See [ConnectionCheckedOutEvent::duration].
225+
#[serde(default = "Duration::default")]
226+
pub duration: Duration,
219227
}
220228

221229
/// The reasons a connection may not be able to be checked out.
@@ -245,6 +253,10 @@ pub struct ConnectionCheckedOutEvent {
245253
/// to identify other events related to this connection.
246254
#[serde(default = "default_connection_id")]
247255
pub connection_id: u32,
256+
257+
/// The time it took to check out the connection.
258+
#[serde(default = "Duration::default")]
259+
pub duration: Duration,
248260
}
249261

250262
/// Event emitted when a connection is checked back into a connection pool.

src/test/spec/json/connection-monitoring-and-pooling/logging/connection-logging.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,13 @@
140140
"int",
141141
"long"
142142
]
143+
},
144+
"durationMS": {
145+
"$$type": [
146+
"double",
147+
"int",
148+
"long"
149+
]
143150
}
144151
}
145152
},
@@ -162,6 +169,13 @@
162169
"int",
163170
"long"
164171
]
172+
},
173+
"durationMS": {
174+
"$$type": [
175+
"double",
176+
"int",
177+
"long"
178+
]
165179
}
166180
}
167181
},
@@ -424,6 +438,13 @@
424438
"reason": "An error occurred while trying to establish a new connection",
425439
"error": {
426440
"$$exists": true
441+
},
442+
"durationMS": {
443+
"$$type": [
444+
"double",
445+
"int",
446+
"long"
447+
]
427448
}
428449
}
429450
}

src/test/spec/json/connection-monitoring-and-pooling/logging/connection-logging.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,16 @@ tests:
6666
driverConnectionId: { $$type: [int, long] }
6767
serverHost: { $$type: string }
6868
serverPort: { $$type: [int, long] }
69-
69+
durationMS: { $$type: [double, int, long] }
70+
7071
- level: debug
7172
component: connection
7273
data:
7374
message: "Connection checked out"
7475
driverConnectionId: { $$type: [int, long] }
7576
serverHost: { $$type: string }
7677
serverPort: { $$type: [int, long] }
78+
durationMS: { $$type: [double, int, long] }
7779

7880
- level: debug
7981
component: connection
@@ -194,3 +196,4 @@ tests:
194196
serverPort: { $$type: [int, long] }
195197
reason: "An error occurred while trying to establish a new connection"
196198
error: { $$exists: true }
199+
durationMS: { $$type: [double, int, long] }

src/test/spec/json/connection-monitoring-and-pooling/logging/connection-pool-options.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"description": "connection-logging",
2+
"description": "connection-pool-options",
33
"schemaVersion": "1.13",
44
"runOnRequirements": [
55
{
@@ -128,6 +128,13 @@
128128
"int",
129129
"long"
130130
]
131+
},
132+
"durationMS": {
133+
"$$type": [
134+
"double",
135+
"int",
136+
"long"
137+
]
131138
}
132139
}
133140
}

src/test/spec/json/connection-monitoring-and-pooling/logging/connection-pool-options.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
description: "connection-logging"
1+
description: "connection-pool-options"
22

33
schemaVersion: "1.13"
44

@@ -71,6 +71,7 @@ tests:
7171
driverConnectionId: { $$type: [int, long] }
7272
serverHost: { $$type: string }
7373
serverPort: { $$type: [int, long] }
74+
durationMS: { $$type: [double, int, long] }
7475

7576
# Drivers who have not done DRIVERS-1943 will need to skip this test.
7677
- description: "maxConnecting should be included in connection pool created message when specified"

src/trace/connection.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ impl CmapEventHandler for ConnectionTracingEventEmitter {
9595
serverHost = event.address.host().as_ref(),
9696
serverPort = event.address.port_tracing_representation(),
9797
driverConnectionId = event.connection_id,
98+
durationMS = event.duration.as_millis(),
9899
"Connection ready",
99100
);
100101
}
@@ -130,6 +131,7 @@ impl CmapEventHandler for ConnectionTracingEventEmitter {
130131
serverPort = event.address.port_tracing_representation(),
131132
reason = event.reason.tracing_representation(),
132133
error = event.error.map(|e| e.tracing_representation()),
134+
durationMS = event.duration.as_millis(),
133135
"Connection checkout failed",
134136
);
135137
}
@@ -141,6 +143,7 @@ impl CmapEventHandler for ConnectionTracingEventEmitter {
141143
serverHost = event.address.host().as_ref(),
142144
serverPort = event.address.port_tracing_representation(),
143145
driverConnectionId = event.connection_id,
146+
durationMS = event.duration.as_millis(),
144147
"Connection checked out",
145148
);
146149
}

0 commit comments

Comments
 (0)