Skip to content

Commit 5759f72

Browse files
committed
refactor(NODE-6230): executeOperation to use iterative retry mechanism (#4157)
1 parent 9c3353b commit 5759f72

File tree

2 files changed

+20
-13
lines changed

2 files changed

+20
-13
lines changed

src/cmap/connection_pool.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import {
2828
import { CancellationToken, TypedEventEmitter } from '../mongo_types';
2929
import type { Server } from '../sdam/server';
3030
import { type TimeoutContext, TimeoutError } from '../timeout';
31-
import { type Callback, List, makeCounter, promiseWithResolvers } from '../utils';
31+
import { type Callback, List, makeCounter, now, promiseWithResolvers } from '../utils';
3232
import { connect } from './connect';
3333
import { Connection, type ConnectionEvents, type ConnectionOptions } from './connection';
3434
import {
@@ -356,6 +356,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
356356
* explicitly destroyed by the new owner.
357357
*/
358358
async checkOut(options: { timeoutContext: TimeoutContext }): Promise<Connection> {
359+
const checkoutTime = now();
359360
this.emitAndLog(
360361
ConnectionPool.CONNECTION_CHECK_OUT_STARTED,
361362
new ConnectionCheckOutStartedEvent(this)
@@ -367,7 +368,8 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
367368

368369
const waitQueueMember: WaitQueueMember = {
369370
resolve,
370-
reject
371+
reject,
372+
checkoutTime
371373
};
372374

373375
this[kWaitQueue].push(waitQueueMember);

src/operations/execute_operation.ts

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import {
2525
import type { Topology } from '../sdam/topology';
2626
import type { ClientSession } from '../sessions';
2727
import { TimeoutContext } from '../timeout';
28-
import { squashError, supportsRetryableWrites } from '../utils';
28+
import { supportsRetryableWrites } from '../utils';
2929
import { AbstractOperation, Aspect } from './operation';
3030

3131
const MMAPv1_RETRY_WRITES_ERROR_CODE = MONGODB_ERROR_CODES.IllegalOperation;
@@ -88,12 +88,6 @@ export async function executeOperation<
8888
);
8989
}
9090

91-
timeoutContext ??= TimeoutContext.create({
92-
serverSelectionTimeoutMS: client.s.options.serverSelectionTimeoutMS,
93-
waitQueueTimeoutMS: client.s.options.waitQueueTimeoutMS,
94-
timeoutMS: operation.options.timeoutMS
95-
});
96-
9791
const readPreference = operation.readPreference ?? ReadPreference.primary;
9892
const inTransaction = !!session?.inTransaction();
9993

@@ -113,12 +107,18 @@ export async function executeOperation<
113107
session.unpin();
114108
}
115109

110+
timeoutContext ??= TimeoutContext.create({
111+
serverSelectionTimeoutMS: client.s.options.serverSelectionTimeoutMS,
112+
waitQueueTimeoutMS: client.s.options.waitQueueTimeoutMS,
113+
timeoutMS: operation.options.timeoutMS
114+
});
115+
116116
try {
117117
return await tryOperation(operation, {
118118
topology,
119+
timeoutContext,
119120
session,
120-
readPreference,
121-
timeoutContext
121+
readPreference
122122
});
123123
} finally {
124124
if (session?.owner != null && session.owner === owner) {
@@ -157,6 +157,7 @@ type RetryOptions = {
157157
session: ClientSession | undefined;
158158
readPreference: ReadPreference;
159159
topology: Topology;
160+
timeoutContext: TimeoutContext;
160161
};
161162

162163
/**
@@ -180,7 +181,10 @@ type RetryOptions = {
180181
async function tryOperation<
181182
T extends AbstractOperation<TResult>,
182183
TResult = ResultTypeFromOperation<T>
183-
>(operation: T, { topology, session, readPreference }: RetryOptions): Promise<TResult> {
184+
>(
185+
operation: T,
186+
{ topology, timeoutContext, session, readPreference }: RetryOptions
187+
): Promise<TResult> {
184188
let selector: ReadPreference | ServerSelector;
185189

186190
if (operation.hasAspect(Aspect.MUST_SELECT_SAME_SERVER)) {
@@ -198,7 +202,8 @@ async function tryOperation<
198202

199203
let server = await topology.selectServer(selector, {
200204
session,
201-
operationName: operation.commandName
205+
operationName: operation.commandName,
206+
timeoutContext
202207
});
203208

204209
const hasReadAspect = operation.hasAspect(Aspect.READ_OPERATION);

0 commit comments

Comments
 (0)