Skip to content

Commit b4fa0ce

Browse files
committed
Add TimeoutContext
1 parent d44b479 commit b4fa0ce

File tree

1 file changed

+82
-2
lines changed

1 file changed

+82
-2
lines changed

src/timeout.ts

Lines changed: 82 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { clearTimeout, setTimeout } from 'timers';
22

3-
import { MongoInvalidArgumentError } from './error';
4-
import { noop } from './utils';
3+
import { MongoInvalidArgumentError, MongoRuntimeError } from './error';
4+
import { csotMin, noop } from './utils';
55

66
/** @internal */
77
export class TimeoutError extends Error {
@@ -108,3 +108,83 @@ export class Timeout extends Promise<never> {
108108
);
109109
}
110110
}
111+
112+
export type TimeoutContextOptions = {
113+
timeoutMS?: number;
114+
serverSelectionTimeoutMS: number;
115+
waitQueueTimeoutMS: number;
116+
socketTimeoutMS: number;
117+
};
118+
119+
export class TimeoutContext {
120+
timeoutMS?: number;
121+
serverSelectionTimeoutMS: number;
122+
waitQueueTimeoutMS: number;
123+
socketTimeoutMS: number;
124+
125+
private _maxTimeMS?: number;
126+
127+
private _serverSelectionTimeout?: Timeout | null;
128+
private _connectionCheckoutTimeout?: Timeout | null;
129+
private _socketWriteTimeout?: Timeout;
130+
private _socketReadTimeout?: Timeout;
131+
132+
constructor(options: TimeoutContextOptions) {
133+
this.timeoutMS = options.timeoutMS;
134+
this.serverSelectionTimeoutMS = options.serverSelectionTimeoutMS;
135+
this.waitQueueTimeoutMS = options.waitQueueTimeoutMS;
136+
this.socketTimeoutMS = options.socketTimeoutMS;
137+
}
138+
139+
get maxTimeMS(): number {
140+
return this._maxTimeMS ?? -1;
141+
}
142+
143+
set maxTimeMS(v: number) {
144+
this._maxTimeMS = v;
145+
}
146+
147+
get serverSelectionTimeout(): Timeout | null {
148+
if (typeof this._serverSelectionTimeout === 'undefined') {
149+
if (this.timeoutMS != null) {
150+
if (this.timeoutMS > 0 && this.serverSelectionTimeoutMS > 0) {
151+
if (
152+
this.timeoutMS === this.serverSelectionTimeoutMS ||
153+
csotMin(this.timeoutMS, this.serverSelectionTimeoutMS) < this.serverSelectionTimeoutMS
154+
) {
155+
this._serverSelectionTimeout = Timeout.expires(this.timeoutMS);
156+
} else {
157+
this._serverSelectionTimeout = Timeout.expires(this.serverSelectionTimeoutMS);
158+
}
159+
} else {
160+
this._serverSelectionTimeout = null;
161+
}
162+
} else {
163+
this._serverSelectionTimeout = Timeout.expires(this.serverSelectionTimeoutMS);
164+
}
165+
}
166+
167+
return this._serverSelectionTimeout;
168+
}
169+
170+
get connectionCheckoutTimeout(): Timeout | null {
171+
if (!this._connectionCheckoutTimeout) {
172+
if (this.timeoutMS != null) {
173+
if (typeof this._serverSelectionTimeout === 'object') {
174+
// null or Timeout
175+
this._connectionCheckoutTimeout = this._serverSelectionTimeout;
176+
} else {
177+
throw new MongoRuntimeError(
178+
'Unreachable. If you are seeing this error, please file a ticket on the NODE driver project on Jira'
179+
);
180+
}
181+
} else {
182+
this._connectionCheckoutTimeout = Timeout.expires(this.waitQueueTimeoutMS);
183+
}
184+
185+
return this._connectionCheckoutTimeout;
186+
} else {
187+
return this._connectionCheckoutTimeout;
188+
}
189+
}
190+
}

0 commit comments

Comments
 (0)