Skip to content

Commit a3c6eb9

Browse files
feat(NODE-5459): add durations to connection pool events
1 parent ec3caba commit a3c6eb9

File tree

4 files changed

+50
-4
lines changed

4 files changed

+50
-4
lines changed

src/cmap/connection.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
191191

192192
private lastUseTime: number;
193193
private clusterTime: Document | null = null;
194+
194195
private error: Error | null = null;
195196
private dataEvents: AsyncGenerator<Buffer, void, void> | null = null;
196197

@@ -229,6 +230,7 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
229230
this.description = new StreamDescription(this.address, options);
230231
this.generation = options.generation;
231232
this.lastUseTime = now();
233+
this.connectionCreatedEventTime = null;
232234

233235
this.messageStream = this.socket
234236
.on('error', this.onError.bind(this))

src/cmap/connection_pool.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
629629

630630
this[kPending]++;
631631
// This is our version of a "virtual" no-I/O connection as the spec requires
632+
const connectionCreatedTime = Date.now();
632633
this.emitAndLog(
633634
ConnectionPool.CONNECTION_CREATED,
634635
new ConnectionCreatedEvent(this, { id: connectOptions.id })
@@ -670,7 +671,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
670671
connection.markAvailable();
671672
this.emitAndLog(
672673
ConnectionPool.CONNECTION_READY,
673-
new ConnectionReadyEvent(this, connection)
674+
new ConnectionReadyEvent(this, connection, connectionCreatedTime)
674675
);
675676

676677
this[kPending]--;

src/cmap/connection_pool_events.ts

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,12 +126,25 @@ export class ConnectionCreatedEvent extends ConnectionPoolMonitoringEvent {
126126
export class ConnectionReadyEvent extends ConnectionPoolMonitoringEvent {
127127
/** The id of the connection */
128128
connectionId: number | '<monitor>';
129+
/**
130+
* The time it took to establish the connection.
131+
* In accordance with the definition of establishment of a connection
132+
* specified by `ConnectionPoolOptions.maxConnecting`,
133+
* it is the time elapsed between emitting a `ConnectionCreatedEvent`
134+
* and emitting this event as part of the same checking out.
135+
*
136+
* Naturally, when establishing a connection is part of checking out,
137+
* this duration is not greater than
138+
* `ConnectionCheckedOutEvent.duration`.
139+
*/
140+
durationMS: number;
129141
/** @internal */
130142
name = CONNECTION_READY;
131143

132144
/** @internal */
133-
constructor(pool: ConnectionPool, connection: Connection) {
145+
constructor(pool: ConnectionPool, connection: Connection, connectionCreatedEventTime: number) {
134146
super(pool);
147+
this.durationMS = Date.now() - connectionCreatedEventTime;
135148
this.connectionId = connection.id;
136149
}
137150
}
@@ -194,6 +207,20 @@ export class ConnectionCheckOutFailedEvent extends ConnectionPoolMonitoringEvent
194207
error?: MongoError;
195208
/** @internal */
196209
name = CONNECTION_CHECK_OUT_FAILED;
210+
/**
211+
* The time it took to check out the connection.
212+
* More specifically, the time elapsed between
213+
* emitting a `ConnectionCheckOutStartedEvent`
214+
* and emitting this event as part of the same checking out.
215+
*
216+
* Naturally, if a new connection was not created (`ConnectionCreatedEvent`)
217+
* and established (`ConnectionReadyEvent`) as part of checking out,
218+
* this duration is usually
219+
* not greater than `ConnectionPoolOptions.waitQueueTimeoutMS`,
220+
* but MAY occasionally be greater than that,
221+
* because a driver does not provide hard real-time guarantees.
222+
*/
223+
durationMS: number;
197224

198225
/** @internal */
199226
constructor(
@@ -202,6 +229,7 @@ export class ConnectionCheckOutFailedEvent extends ConnectionPoolMonitoringEvent
202229
error?: MongoError
203230
) {
204231
super(pool);
232+
this.durationMS = this.durationMS = Date.now() - (connection.connectionCreatedEventTime ?? Date.now());
205233
this.reason = reason;
206234
this.error = error;
207235
}
@@ -217,10 +245,25 @@ export class ConnectionCheckedOutEvent extends ConnectionPoolMonitoringEvent {
217245
connectionId: number | '<monitor>';
218246
/** @internal */
219247
name = CONNECTION_CHECKED_OUT;
248+
/**
249+
* The time it took to check out the connection.
250+
* More specifically, the time elapsed between
251+
* emitting a `ConnectionCheckOutStartedEvent`
252+
* and emitting this event as part of the same checking out.
253+
*
254+
* Naturally, if a new connection was not created (`ConnectionCreatedEvent`)
255+
* and established (`ConnectionReadyEvent`) as part of checking out,
256+
* this duration is usually
257+
* not greater than `ConnectionPoolOptions.waitQueueTimeoutMS`,
258+
* but MAY occasionally be greater than that,
259+
* because a driver does not provide hard real-time guarantees.
260+
*/
261+
durationMS: number;
220262

221263
/** @internal */
222264
constructor(pool: ConnectionPool, connection: Connection) {
223265
super(pool);
266+
this.durationMS = 0;
224267
this.connectionId = connection.id;
225268
}
226269
}

test/integration/connection-monitoring-and-pooling/connection_monitoring_and_pooling.spec.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ const INTERRUPT_IN_USE_SKIPPED_TESTS: SkipDescription[] = [
3939
}
4040
];
4141

42-
describe('Connection Monitoring and Pooling Spec Tests (Integration) - cmap-format', function () {
42+
describe.only('Connection Monitoring and Pooling Spec Tests (Integration) - cmap-format', function () {
4343
const tests: CmapTest[] = loadSpecTests('connection-monitoring-and-pooling', 'cmap-format');
4444

4545
runCmapTestSuite(tests, {
@@ -57,7 +57,7 @@ describe('Connection Monitoring and Pooling Spec Tests (Integration) - cmap-form
5757
});
5858
});
5959

60-
describe('Connection Monitoring and Pooling Spec Tests (Integration) - logging', function () {
60+
describe.only('Connection Monitoring and Pooling Spec Tests (Integration) - logging', function () {
6161
const tests = loadSpecTests('connection-monitoring-and-pooling', 'logging');
6262

6363
runUnifiedSuite(tests, test => {

0 commit comments

Comments
 (0)