@@ -27,8 +27,8 @@ import {
2727} from '../error' ;
2828import { CancellationToken , TypedEventEmitter } from '../mongo_types' ;
2929import type { Server } from '../sdam/server' ;
30- import { Timeout , TimeoutError } from '../timeout' ;
31- import { type Callback , csotMin , List , makeCounter , promiseWithResolvers } from '../utils' ;
30+ import { type TimeoutContext , TimeoutError } from '../timeout' ;
31+ import { type Callback , List , makeCounter , promiseWithResolvers } from '../utils' ;
3232import { connect } from './connect' ;
3333import { Connection , type ConnectionEvents , type ConnectionOptions } from './connection' ;
3434import {
@@ -354,41 +354,15 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
354354 * will be held by the pool. This means that if a connection is checked out it MUST be checked back in or
355355 * explicitly destroyed by the new owner.
356356 */
357- async checkOut ( options ? : { timeout ?: Timeout } ) : Promise < Connection > {
357+ async checkOut ( options : { timeoutContext : TimeoutContext } ) : Promise < Connection > {
358358 this . emitAndLog (
359359 ConnectionPool . CONNECTION_CHECK_OUT_STARTED ,
360360 new ConnectionCheckOutStartedEvent ( this )
361361 ) ;
362362
363- const waitQueueTimeoutMS = this . options . waitQueueTimeoutMS ;
364- const serverSelectionTimeoutMS = this [ kServer ] . topology . s . serverSelectionTimeoutMS ;
365-
366363 const { promise, resolve, reject } = promiseWithResolvers < Connection > ( ) ;
367364
368- let timeout : Timeout | null = null ;
369- if ( options ?. timeout ) {
370- // CSOT enabled
371- // Determine if we're using the timeout passed in or a new timeout
372- if ( options . timeout . duration > 0 || serverSelectionTimeoutMS > 0 ) {
373- // This check determines whether or not Topology.selectServer used the configured
374- // `timeoutMS` or `serverSelectionTimeoutMS` value for its timeout
375- if (
376- options . timeout . duration === serverSelectionTimeoutMS ||
377- csotMin ( options . timeout . duration , serverSelectionTimeoutMS ) < serverSelectionTimeoutMS
378- ) {
379- // server selection used `timeoutMS`, so we should use the existing timeout as the timeout
380- // here
381- timeout = options . timeout ;
382- } else {
383- // server selection used `serverSelectionTimeoutMS`, so we construct a new timeout with
384- // the time remaining to ensure that Topology.selectServer and ConnectionPool.checkOut
385- // cumulatively don't spend more than `serverSelectionTimeoutMS` blocking
386- timeout = Timeout . expires ( serverSelectionTimeoutMS - options . timeout . timeElapsed ) ;
387- }
388- }
389- } else {
390- timeout = Timeout . expires ( waitQueueTimeoutMS ) ;
391- }
365+ const timeout = options . timeoutContext . connectionCheckoutTimeout ;
392366
393367 const waitQueueMember : WaitQueueMember = {
394368 resolve,
@@ -403,6 +377,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
403377 return await ( timeout ? Promise . race ( [ promise , timeout ] ) : promise ) ;
404378 } catch ( error ) {
405379 if ( TimeoutError . is ( error ) ) {
380+ timeout ?. clear ( ) ;
406381 waitQueueMember [ kCancelled ] = true ;
407382
408383 this . emitAndLog (
@@ -415,7 +390,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
415390 : 'Timed out while checking out a connection from connection pool' ,
416391 this . address
417392 ) ;
418- if ( options ?. timeout ) {
393+ if ( options . timeoutContext . csotEnabled ( ) ) {
419394 throw new MongoOperationTimeoutError ( 'Timed out during connection checkout' , {
420395 cause : timeoutError
421396 } ) ;
@@ -424,7 +399,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
424399 }
425400 throw error ;
426401 } finally {
427- if ( timeout !== options ?. timeout ) timeout ?. clear ( ) ;
402+ if ( options . timeoutContext . clearConnectionCheckoutTimeout ) timeout ?. clear ( ) ;
428403 }
429404 }
430405
0 commit comments