Skip to content

Commit 16c38e2

Browse files
committed
always construct TopologyPrivate
1 parent 13898ed commit 16c38e2

File tree

1 file changed

+64
-61
lines changed

1 file changed

+64
-61
lines changed

src/sdam/topology.ts

Lines changed: 64 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ import {
6161
STATE_CLOSING,
6262
STATE_CONNECTED,
6363
STATE_CONNECTING,
64+
STATE_UNITIALIZED,
6465
type TimerQueue,
6566
TopologyType
6667
} from './common';
@@ -89,6 +90,7 @@ import { TopologyDescription } from './topology_description';
8990
let globalTopologyCounter = 0;
9091

9192
const stateTransition = makeStateMachine({
93+
[STATE_UNITIALIZED]: [STATE_CONNECTING, STATE_CLOSING],
9294
[STATE_CLOSED]: [STATE_CLOSED, STATE_CONNECTING],
9395
[STATE_CONNECTING]: [STATE_CONNECTING, STATE_CLOSING, STATE_CONNECTED, STATE_CLOSED],
9496
[STATE_CONNECTED]: [STATE_CONNECTED, STATE_CLOSING, STATE_CLOSED],
@@ -215,7 +217,7 @@ export type TopologyEvents = {
215217
*/
216218
export class Topology extends TypedEventEmitter<TopologyEvents> {
217219
/** @internal */
218-
s!: TopologyPrivate;
220+
s: TopologyPrivate;
219221
/** @internal */
220222
[kWaitQueue]: List<ServerSelectionRequest>;
221223
/** @internal */
@@ -262,6 +264,55 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
262264
this.client = client;
263265
this.options = options;
264266
this[kWaitQueue] = new List();
267+
268+
const topologyId = globalTopologyCounter++;
269+
this.s = {
270+
// the id of this topology
271+
id: topologyId,
272+
// passed in options
273+
options,
274+
seedlist: [],
275+
// initial state
276+
state: STATE_UNITIALIZED,
277+
// the topology description
278+
description: new TopologyDescription(TopologyType.Unknown),
279+
serverSelectionTimeoutMS: options.serverSelectionTimeoutMS,
280+
heartbeatFrequencyMS: options.heartbeatFrequencyMS,
281+
minHeartbeatFrequencyMS: options.minHeartbeatFrequencyMS,
282+
// a map of server instances to normalized addresses
283+
servers: new Map(),
284+
credentials: options?.credentials,
285+
clusterTime: undefined,
286+
287+
// timer management
288+
connectionTimers: new Set<NodeJS.Timeout>(),
289+
detectShardedTopology: ev => this.detectShardedTopology(ev),
290+
detectSrvRecords: ev => this.detectSrvRecords(ev)
291+
};
292+
this.mongoLogger = this.client.mongoLogger;
293+
this.component = 'topology';
294+
295+
if (options.srvHost && !options.loadBalanced) {
296+
this.s.srvPoller =
297+
// @ts-expect-error: todo
298+
options.srvPoller ??
299+
new SrvPoller({
300+
heartbeatFrequencyMS: this.s.heartbeatFrequencyMS,
301+
srvHost: options.srvHost,
302+
srvMaxHosts: options.srvMaxHosts,
303+
srvServiceName: options.srvServiceName
304+
});
305+
306+
this.on(Topology.TOPOLOGY_DESCRIPTION_CHANGED, this.s.detectShardedTopology);
307+
}
308+
// Events can be emitted before initialization is complete so we have to
309+
// save the reference to the topology on the client ASAP if the event handlers need to access it
310+
311+
this.once(Topology.OPEN, () => this.client.emit('open', this.client));
312+
313+
for (const event of MONGO_CLIENT_EVENTS) {
314+
this.on(event, (...args: any[]) => this.client.emit(event, ...(args as any)));
315+
}
265316
}
266317

267318
async init() {
@@ -337,7 +388,6 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
337388
}
338389

339390
const topologyType = topologyTypeFromOptions(options);
340-
const topologyId = globalTopologyCounter++;
341391

342392
const selectedHosts =
343393
options.srvMaxHosts == null ||
@@ -351,64 +401,17 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
351401
serverDescriptions.set(hostAddress.toString(), new ServerDescription(hostAddress));
352402
}
353403

354-
this.s = {
355-
// the id of this topology
356-
id: topologyId,
357-
// passed in options
358-
options,
359-
// initial seedlist of servers to connect to
360-
seedlist,
361-
// initial state
362-
state: STATE_CLOSED,
363-
// the topology description
364-
description: new TopologyDescription(
365-
topologyType,
366-
serverDescriptions,
367-
options.replicaSet,
368-
undefined,
369-
undefined,
370-
undefined,
371-
options
372-
),
373-
serverSelectionTimeoutMS: options.serverSelectionTimeoutMS,
374-
heartbeatFrequencyMS: options.heartbeatFrequencyMS,
375-
minHeartbeatFrequencyMS: options.minHeartbeatFrequencyMS,
376-
// a map of server instances to normalized addresses
377-
servers: new Map(),
378-
credentials: options?.credentials,
379-
clusterTime: undefined,
380-
381-
// timer management
382-
connectionTimers: new Set<NodeJS.Timeout>(),
383-
detectShardedTopology: ev => this.detectShardedTopology(ev),
384-
detectSrvRecords: ev => this.detectSrvRecords(ev)
385-
};
386-
387-
this.mongoLogger = this.client.mongoLogger;
388-
this.component = 'topology';
389-
390-
if (options.srvHost && !options.loadBalanced) {
391-
this.s.srvPoller =
392-
// @ts-expect-error: todo
393-
options.srvPoller ??
394-
new SrvPoller({
395-
heartbeatFrequencyMS: this.s.heartbeatFrequencyMS,
396-
srvHost: options.srvHost,
397-
srvMaxHosts: options.srvMaxHosts,
398-
srvServiceName: options.srvServiceName
399-
});
400-
401-
this.on(Topology.TOPOLOGY_DESCRIPTION_CHANGED, this.s.detectShardedTopology);
402-
}
403-
404-
// Events can be emitted before initialization is complete so we have to
405-
// save the reference to the topology on the client ASAP if the event handlers need to access it
406-
407-
this.once(Topology.OPEN, () => this.client.emit('open', this.client));
408-
409-
for (const event of MONGO_CLIENT_EVENTS) {
410-
this.on(event, (...args: any[]) => this.client.emit(event, ...(args as any)));
411-
}
404+
this.s.description = new TopologyDescription(
405+
topologyType,
406+
serverDescriptions,
407+
options.replicaSet,
408+
undefined,
409+
undefined,
410+
undefined,
411+
options
412+
);
413+
// initial seedlist of servers to connect to
414+
this.s.seedlist = seedlist;
412415
}
413416

414417
private detectShardedTopology(event: TopologyDescriptionChangedEvent) {
@@ -510,7 +513,7 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
510513
selector: string | ReadPreference | ServerSelector,
511514
options: SelectServerOptions
512515
): Promise<Server> {
513-
const shouldInitialize = this.s == null;
516+
const shouldInitialize = this.s.state === STATE_UNITIALIZED;
514517
if (shouldInitialize) {
515518
await this.init();
516519
this.stateTransition(STATE_CONNECTING);

0 commit comments

Comments
 (0)