@@ -39,6 +39,7 @@ export class Timeout extends Promise<never> {
39
39
public ended : number | null = null ;
40
40
public duration : number ;
41
41
public timedOut = false ;
42
+ public cleared = false ;
42
43
43
44
get remainingTime ( ) : number {
44
45
if ( this . timedOut ) return 0 ;
@@ -53,7 +54,6 @@ export class Timeout extends Promise<never> {
53
54
/** Create a new timeout that expires in `duration` ms */
54
55
private constructor ( executor : Executor = ( ) => null , duration : number , unref = true ) {
55
56
let reject ! : Reject ;
56
-
57
57
if ( duration < 0 ) {
58
58
throw new MongoInvalidArgumentError ( 'Cannot create a Timeout with a negative duration' ) ;
59
59
}
@@ -86,6 +86,7 @@ export class Timeout extends Promise<never> {
86
86
clear ( ) : void {
87
87
clearTimeout ( this . id ) ;
88
88
this . id = undefined ;
89
+ this . cleared = true ;
89
90
}
90
91
91
92
throwIfExpired ( ) : void {
@@ -213,16 +214,20 @@ export class CSOTTimeoutContext extends TimeoutContext {
213
214
214
215
get serverSelectionTimeout ( ) : Timeout | null {
215
216
// check for undefined
216
- if ( typeof this . _serverSelectionTimeout !== 'object' ) {
217
+ if ( typeof this . _serverSelectionTimeout !== 'object' || this . _serverSelectionTimeout ?. cleared ) {
218
+ const { remainingTimeMS, serverSelectionTimeoutMS } = this ;
219
+ if ( remainingTimeMS <= 0 )
220
+ throw new MongoOperationTimeoutError (
221
+ `Timed out in server selection after ${ this . timeoutMS } ms`
222
+ ) ;
217
223
const usingServerSelectionTimeoutMS =
218
- this . serverSelectionTimeoutMS !== 0 &&
219
- csotMin ( this . timeoutMS , this . serverSelectionTimeoutMS ) === this . serverSelectionTimeoutMS ;
220
-
224
+ serverSelectionTimeoutMS !== 0 &&
225
+ csotMin ( remainingTimeMS , serverSelectionTimeoutMS ) === serverSelectionTimeoutMS ;
221
226
if ( usingServerSelectionTimeoutMS ) {
222
- this . _serverSelectionTimeout = Timeout . expires ( this . serverSelectionTimeoutMS ) ;
227
+ this . _serverSelectionTimeout = Timeout . expires ( serverSelectionTimeoutMS ) ;
223
228
} else {
224
- if ( this . timeoutMS > 0 ) {
225
- this . _serverSelectionTimeout = Timeout . expires ( this . timeoutMS ) ;
229
+ if ( remainingTimeMS > 0 && Number . isFinite ( remainingTimeMS ) ) {
230
+ this . _serverSelectionTimeout = Timeout . expires ( remainingTimeMS ) ;
226
231
} else {
227
232
this . _serverSelectionTimeout = null ;
228
233
}
@@ -233,7 +238,10 @@ export class CSOTTimeoutContext extends TimeoutContext {
233
238
}
234
239
235
240
get connectionCheckoutTimeout ( ) : Timeout | null {
236
- if ( typeof this . _connectionCheckoutTimeout !== 'object' ) {
241
+ if (
242
+ typeof this . _connectionCheckoutTimeout !== 'object' ||
243
+ this . _connectionCheckoutTimeout ?. cleared
244
+ ) {
237
245
if ( typeof this . _serverSelectionTimeout === 'object' ) {
238
246
// null or Timeout
239
247
this . _connectionCheckoutTimeout = this . _serverSelectionTimeout ;
0 commit comments