mongodb 3.5.1 → 3.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/HISTORY.md +11 -0
- package/lib/cmap/connection.js +10 -7
- package/lib/core/error.js +3 -8
- package/lib/core/sdam/server.js +5 -5
- package/lib/core/sdam/server_selection.js +0 -89
- package/lib/core/sdam/topology.js +109 -26
- package/package.json +1 -1
package/HISTORY.md
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
<a name="3.5.2"></a>
|
|
6
|
+
## [3.5.2](https://github.com/mongodb/node-mongodb-native/compare/v3.5.1...v3.5.2) (2020-01-20)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* properly handle err messages in MongoDB 2.6 servers ([0f4ab38](https://github.com/mongodb/node-mongodb-native/commit/0f4ab38))
|
|
12
|
+
* **topology:** always emit SDAM unrecoverable errors ([57f158f](https://github.com/mongodb/node-mongodb-native/commit/57f158f))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
5
16
|
<a name="3.5.1"></a>
|
|
6
17
|
## [3.5.1](https://github.com/mongodb/node-mongodb-native/compare/v3.5.0...v3.5.1) (2020-01-17)
|
|
7
18
|
|
package/lib/cmap/connection.js
CHANGED
|
@@ -243,14 +243,16 @@ function messageHandler(conn) {
|
|
|
243
243
|
conn.emit('clusterTimeReceived', document.$clusterTime);
|
|
244
244
|
}
|
|
245
245
|
|
|
246
|
-
if (
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
246
|
+
if (operationDescription.command) {
|
|
247
|
+
if (document.writeConcernError) {
|
|
248
|
+
callback(new MongoWriteConcernError(document.writeConcernError, document));
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
250
251
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
252
|
+
if (document.ok === 0 || document.$err || document.errmsg || document.code) {
|
|
253
|
+
callback(new MongoError(document));
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
254
256
|
}
|
|
255
257
|
}
|
|
256
258
|
|
|
@@ -290,6 +292,7 @@ function write(command, options, callback) {
|
|
|
290
292
|
fullResult: typeof options.fullResult === 'boolean' ? options.fullResult : false,
|
|
291
293
|
noResponse: typeof options.noResponse === 'boolean' ? options.noResponse : false,
|
|
292
294
|
documentsReturnedIn: options.documentsReturnedIn,
|
|
295
|
+
command: !!options.command,
|
|
293
296
|
|
|
294
297
|
// for BSON parsing
|
|
295
298
|
promoteLongs: typeof options.promoteLongs === 'boolean' ? options.promoteLongs : true,
|
package/lib/core/error.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const mongoErrorContextSymbol = Symbol('mongoErrorContextSymbol');
|
|
4
|
-
const maxWireVersion = require('./utils').maxWireVersion;
|
|
5
4
|
|
|
6
5
|
/**
|
|
7
6
|
* Creates a new MongoError
|
|
@@ -237,9 +236,8 @@ function isNodeShuttingDownError(err) {
|
|
|
237
236
|
* @ignore
|
|
238
237
|
* @see https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring.rst#not-master-and-node-is-recovering
|
|
239
238
|
* @param {MongoError|Error} error
|
|
240
|
-
* @param {Server} server
|
|
241
239
|
*/
|
|
242
|
-
function isSDAMUnrecoverableError(error
|
|
240
|
+
function isSDAMUnrecoverableError(error) {
|
|
243
241
|
// NOTE: null check is here for a strictly pre-CMAP world, a timeout or
|
|
244
242
|
// close event are considered unrecoverable
|
|
245
243
|
if (error instanceof MongoParseError || error == null) {
|
|
@@ -247,10 +245,6 @@ function isSDAMUnrecoverableError(error, server) {
|
|
|
247
245
|
}
|
|
248
246
|
|
|
249
247
|
if (isRecoveringError(error) || isNotMasterError(error)) {
|
|
250
|
-
if (maxWireVersion(server) >= 8 && !isNodeShuttingDownError(error)) {
|
|
251
|
-
return false;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
248
|
return true;
|
|
255
249
|
}
|
|
256
250
|
|
|
@@ -266,5 +260,6 @@ module.exports = {
|
|
|
266
260
|
MongoWriteConcernError,
|
|
267
261
|
mongoErrorContextSymbol,
|
|
268
262
|
isRetryableError,
|
|
269
|
-
isSDAMUnrecoverableError
|
|
263
|
+
isSDAMUnrecoverableError,
|
|
264
|
+
isNodeShuttingDownError
|
|
270
265
|
};
|
package/lib/core/sdam/server.js
CHANGED
|
@@ -286,7 +286,7 @@ class Server extends EventEmitter {
|
|
|
286
286
|
options.session.serverSession.isDirty = true;
|
|
287
287
|
}
|
|
288
288
|
|
|
289
|
-
if (isSDAMUnrecoverableError(err
|
|
289
|
+
if (isSDAMUnrecoverableError(err)) {
|
|
290
290
|
this.emit('error', err);
|
|
291
291
|
}
|
|
292
292
|
}
|
|
@@ -319,7 +319,7 @@ class Server extends EventEmitter {
|
|
|
319
319
|
options.session.serverSession.isDirty = true;
|
|
320
320
|
}
|
|
321
321
|
|
|
322
|
-
if (isSDAMUnrecoverableError(err
|
|
322
|
+
if (isSDAMUnrecoverableError(err)) {
|
|
323
323
|
this.emit('error', err);
|
|
324
324
|
}
|
|
325
325
|
}
|
|
@@ -352,7 +352,7 @@ class Server extends EventEmitter {
|
|
|
352
352
|
options.session.serverSession.isDirty = true;
|
|
353
353
|
}
|
|
354
354
|
|
|
355
|
-
if (isSDAMUnrecoverableError(err
|
|
355
|
+
if (isSDAMUnrecoverableError(err)) {
|
|
356
356
|
this.emit('error', err);
|
|
357
357
|
}
|
|
358
358
|
}
|
|
@@ -382,7 +382,7 @@ class Server extends EventEmitter {
|
|
|
382
382
|
if (err) return cb(err);
|
|
383
383
|
|
|
384
384
|
conn.killCursors(ns, cursorState, (err, result) => {
|
|
385
|
-
if (err && isSDAMUnrecoverableError(err
|
|
385
|
+
if (err && isSDAMUnrecoverableError(err)) {
|
|
386
386
|
this.emit('error', err);
|
|
387
387
|
}
|
|
388
388
|
|
|
@@ -489,7 +489,7 @@ function executeWriteOperation(args, options, callback) {
|
|
|
489
489
|
options.session.serverSession.isDirty = true;
|
|
490
490
|
}
|
|
491
491
|
|
|
492
|
-
if (isSDAMUnrecoverableError(err
|
|
492
|
+
if (isSDAMUnrecoverableError(err)) {
|
|
493
493
|
server.emit('error', err);
|
|
494
494
|
}
|
|
495
495
|
}
|
|
@@ -3,12 +3,6 @@ const ServerType = require('./common').ServerType;
|
|
|
3
3
|
const TopologyType = require('./common').TopologyType;
|
|
4
4
|
const ReadPreference = require('../topologies/read_preference');
|
|
5
5
|
const MongoError = require('../error').MongoError;
|
|
6
|
-
const calculateDurationInMs = require('../utils').calculateDurationInMs;
|
|
7
|
-
const MongoServerSelectionError = require('../error').MongoServerSelectionError;
|
|
8
|
-
|
|
9
|
-
const common = require('./common');
|
|
10
|
-
const STATE_CLOSED = common.STATE_CLOSED;
|
|
11
|
-
const clearAndRemoveTimerFrom = common.clearAndRemoveTimerFrom;
|
|
12
6
|
|
|
13
7
|
// max staleness constants
|
|
14
8
|
const IDLE_WRITE_PERIOD = 10000;
|
|
@@ -246,90 +240,7 @@ function readPreferenceServerSelector(readPreference) {
|
|
|
246
240
|
};
|
|
247
241
|
}
|
|
248
242
|
|
|
249
|
-
/**
|
|
250
|
-
* Selects servers using the provided selector
|
|
251
|
-
*
|
|
252
|
-
* @private
|
|
253
|
-
* @param {Topology} topology The topology to select servers from
|
|
254
|
-
* @param {function} selector The predicate used for selecting servers
|
|
255
|
-
* @param {Number} timeout The max time we are willing wait for selection
|
|
256
|
-
* @param {Number} start A high precision timestamp for the start of the selection process
|
|
257
|
-
* @param {function} callback The callback used to convey errors or the resultant servers
|
|
258
|
-
*/
|
|
259
|
-
function selectServers(topology, selector, timeout, start, callback) {
|
|
260
|
-
const duration = calculateDurationInMs(start);
|
|
261
|
-
if (duration >= timeout) {
|
|
262
|
-
return callback(
|
|
263
|
-
new MongoServerSelectionError(`Server selection timed out after ${timeout} ms`),
|
|
264
|
-
topology.description
|
|
265
|
-
);
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
// explicitly disallow selection if client is closed
|
|
269
|
-
if (topology.s.state === STATE_CLOSED) {
|
|
270
|
-
callback(new MongoError('Topology is closed, please connect'));
|
|
271
|
-
return;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
// otherwise, attempt server selection
|
|
275
|
-
const serverDescriptions = Array.from(topology.description.servers.values());
|
|
276
|
-
let descriptions;
|
|
277
|
-
|
|
278
|
-
// support server selection by options with readPreference
|
|
279
|
-
if (typeof selector === 'object') {
|
|
280
|
-
const readPreference = selector.readPreference
|
|
281
|
-
? selector.readPreference
|
|
282
|
-
: ReadPreference.primary;
|
|
283
|
-
|
|
284
|
-
selector = readPreferenceServerSelector(readPreference);
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
try {
|
|
288
|
-
descriptions = selector
|
|
289
|
-
? selector(topology.description, serverDescriptions)
|
|
290
|
-
: serverDescriptions;
|
|
291
|
-
} catch (e) {
|
|
292
|
-
return callback(e, null);
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
if (descriptions.length) {
|
|
296
|
-
const servers = descriptions.map(description => topology.s.servers.get(description.address));
|
|
297
|
-
return callback(null, servers);
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
const retrySelection = () => {
|
|
301
|
-
// ensure all server monitors attempt monitoring soon
|
|
302
|
-
topology.s.servers.forEach(server => process.nextTick(() => server.requestCheck()));
|
|
303
|
-
|
|
304
|
-
const iterationTimer = setTimeout(() => {
|
|
305
|
-
topology.removeListener('topologyDescriptionChanged', descriptionChangedHandler);
|
|
306
|
-
callback(
|
|
307
|
-
new MongoServerSelectionError(
|
|
308
|
-
`Server selection timed out after ${timeout} ms`,
|
|
309
|
-
topology.description
|
|
310
|
-
)
|
|
311
|
-
);
|
|
312
|
-
}, timeout - duration);
|
|
313
|
-
|
|
314
|
-
const descriptionChangedHandler = () => {
|
|
315
|
-
// successful iteration, clear the check timer
|
|
316
|
-
clearAndRemoveTimerFrom(iterationTimer, topology.s.iterationTimers);
|
|
317
|
-
|
|
318
|
-
// topology description has changed due to monitoring, reattempt server selection
|
|
319
|
-
selectServers(topology, selector, timeout, start, callback);
|
|
320
|
-
};
|
|
321
|
-
|
|
322
|
-
// track this timer in case we need to clean it up outside this loop
|
|
323
|
-
topology.s.iterationTimers.add(iterationTimer);
|
|
324
|
-
|
|
325
|
-
topology.once('topologyDescriptionChanged', descriptionChangedHandler);
|
|
326
|
-
};
|
|
327
|
-
|
|
328
|
-
retrySelection();
|
|
329
|
-
}
|
|
330
|
-
|
|
331
243
|
module.exports = {
|
|
332
|
-
selectServers,
|
|
333
244
|
writableServerSelector,
|
|
334
245
|
readPreferenceServerSelector
|
|
335
246
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
+
const Denque = require('denque');
|
|
2
3
|
const EventEmitter = require('events');
|
|
3
4
|
const ServerDescription = require('./server_description').ServerDescription;
|
|
4
5
|
const ServerType = require('./common').ServerType;
|
|
@@ -14,9 +15,11 @@ const deprecate = require('util').deprecate;
|
|
|
14
15
|
const BSON = require('../connection/utils').retrieveBSON();
|
|
15
16
|
const createCompressionInfo = require('../topologies/shared').createCompressionInfo;
|
|
16
17
|
const isRetryableError = require('../error').isRetryableError;
|
|
17
|
-
const
|
|
18
|
+
const isNodeShuttingDownError = require('../error').isNodeShuttingDownError;
|
|
19
|
+
const maxWireVersion = require('../utils').maxWireVersion;
|
|
18
20
|
const ClientSession = require('../sessions').ClientSession;
|
|
19
21
|
const MongoError = require('../error').MongoError;
|
|
22
|
+
const MongoServerSelectionError = require('../error').MongoServerSelectionError;
|
|
20
23
|
const resolveClusterTime = require('../topologies/shared').resolveClusterTime;
|
|
21
24
|
const SrvPoller = require('./srv_polling').SrvPoller;
|
|
22
25
|
const getMMAPError = require('../topologies/shared').getMMAPError;
|
|
@@ -34,7 +37,7 @@ const clearAndRemoveTimerFrom = common.clearAndRemoveTimerFrom;
|
|
|
34
37
|
const serverSelection = require('./server_selection');
|
|
35
38
|
const readPreferenceServerSelector = serverSelection.readPreferenceServerSelector;
|
|
36
39
|
const writableServerSelector = serverSelection.writableServerSelector;
|
|
37
|
-
const selectServers = serverSelection.selectServers;
|
|
40
|
+
// const selectServers = serverSelection.selectServers;
|
|
38
41
|
|
|
39
42
|
// Global state
|
|
40
43
|
let globalTopologyCounter = 0;
|
|
@@ -73,6 +76,9 @@ const DEPRECATED_OPTIONS = new Set([
|
|
|
73
76
|
'bufferMaxEntries'
|
|
74
77
|
]);
|
|
75
78
|
|
|
79
|
+
const kCancelled = Symbol('cancelled');
|
|
80
|
+
const kWaitQueue = Symbol('waitQueue');
|
|
81
|
+
|
|
76
82
|
/**
|
|
77
83
|
* A container of server instances representing a connection to a MongoDB topology.
|
|
78
84
|
*
|
|
@@ -139,6 +145,7 @@ class Topology extends EventEmitter {
|
|
|
139
145
|
return result;
|
|
140
146
|
}, new Map());
|
|
141
147
|
|
|
148
|
+
this[kWaitQueue] = new Denque();
|
|
142
149
|
this.s = {
|
|
143
150
|
// the id of this topology
|
|
144
151
|
id: topologyId,
|
|
@@ -194,7 +201,6 @@ class Topology extends EventEmitter {
|
|
|
194
201
|
clusterTime: null,
|
|
195
202
|
|
|
196
203
|
// timer management
|
|
197
|
-
iterationTimers: new Set(),
|
|
198
204
|
connectionTimers: new Set()
|
|
199
205
|
};
|
|
200
206
|
|
|
@@ -334,8 +340,7 @@ class Topology extends EventEmitter {
|
|
|
334
340
|
return;
|
|
335
341
|
}
|
|
336
342
|
|
|
337
|
-
|
|
338
|
-
drainTimerQueue(this.s.iterationTimers);
|
|
343
|
+
drainWaitQueue(this[kWaitQueue], new MongoError('Topology closed'));
|
|
339
344
|
drainTimerQueue(this.s.connectionTimers);
|
|
340
345
|
|
|
341
346
|
if (this.s.srvPoller) {
|
|
@@ -415,26 +420,43 @@ class Topology extends EventEmitter {
|
|
|
415
420
|
const transaction = session && session.transaction;
|
|
416
421
|
|
|
417
422
|
if (isSharded && transaction && transaction.server) {
|
|
418
|
-
callback(
|
|
423
|
+
callback(undefined, transaction.server);
|
|
419
424
|
return;
|
|
420
425
|
}
|
|
421
426
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
if (err) return callback(err);
|
|
429
|
-
|
|
430
|
-
const selectedServer = randomSelection(servers);
|
|
431
|
-
if (isSharded && transaction && transaction.isActive) {
|
|
432
|
-
transaction.pinServer(selectedServer);
|
|
433
|
-
}
|
|
427
|
+
// support server selection by options with readPreference
|
|
428
|
+
let serverSelector = selector;
|
|
429
|
+
if (typeof selector === 'object') {
|
|
430
|
+
const readPreference = selector.readPreference
|
|
431
|
+
? selector.readPreference
|
|
432
|
+
: ReadPreference.primary;
|
|
434
433
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
434
|
+
serverSelector = readPreferenceServerSelector(readPreference);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
const waitQueueMember = {
|
|
438
|
+
serverSelector,
|
|
439
|
+
transaction,
|
|
440
|
+
callback
|
|
441
|
+
};
|
|
442
|
+
|
|
443
|
+
const serverSelectionTimeoutMS = options.serverSelectionTimeoutMS;
|
|
444
|
+
if (serverSelectionTimeoutMS) {
|
|
445
|
+
waitQueueMember.timer = setTimeout(() => {
|
|
446
|
+
waitQueueMember[kCancelled] = true;
|
|
447
|
+
waitQueueMember.timer = undefined;
|
|
448
|
+
const timeoutError = new MongoServerSelectionError(
|
|
449
|
+
`Server selection timed out after ${serverSelectionTimeoutMS} ms`,
|
|
450
|
+
this.description
|
|
451
|
+
);
|
|
452
|
+
|
|
453
|
+
waitQueueMember.callback(timeoutError);
|
|
454
|
+
}, serverSelectionTimeoutMS);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
// place the member at the front of the wait queue
|
|
458
|
+
this[kWaitQueue].unshift(waitQueueMember);
|
|
459
|
+
processWaitQueue(this);
|
|
438
460
|
}
|
|
439
461
|
|
|
440
462
|
// Sessions related methods
|
|
@@ -544,6 +566,11 @@ class Topology extends EventEmitter {
|
|
|
544
566
|
// update server list from updated descriptions
|
|
545
567
|
updateServers(this, serverDescription);
|
|
546
568
|
|
|
569
|
+
// attempt to resolve any outstanding server selection attempts
|
|
570
|
+
if (this[kWaitQueue].length > 0) {
|
|
571
|
+
processWaitQueue(this);
|
|
572
|
+
}
|
|
573
|
+
|
|
547
574
|
this.emit(
|
|
548
575
|
'topologyDescriptionChanged',
|
|
549
576
|
new events.TopologyDescriptionChangedEvent(
|
|
@@ -881,14 +908,12 @@ function serverErrorEventHandler(server, topology) {
|
|
|
881
908
|
return;
|
|
882
909
|
}
|
|
883
910
|
|
|
884
|
-
if (
|
|
885
|
-
|
|
886
|
-
// we presently _always_ clear the pool on error.
|
|
887
|
-
resetServerState(server, err, { clearPool: true });
|
|
911
|
+
if (maxWireVersion(server) >= 8 && !isNodeShuttingDownError(err)) {
|
|
912
|
+
resetServerState(server, err);
|
|
888
913
|
return;
|
|
889
914
|
}
|
|
890
915
|
|
|
891
|
-
resetServerState(server, err);
|
|
916
|
+
resetServerState(server, err, { clearPool: true });
|
|
892
917
|
};
|
|
893
918
|
}
|
|
894
919
|
|
|
@@ -1013,6 +1038,64 @@ function srvPollingHandler(topology) {
|
|
|
1013
1038
|
};
|
|
1014
1039
|
}
|
|
1015
1040
|
|
|
1041
|
+
function drainWaitQueue(queue, err) {
|
|
1042
|
+
while (queue.length) {
|
|
1043
|
+
const waitQueueMember = queue.pop();
|
|
1044
|
+
clearTimeout(waitQueueMember.timer);
|
|
1045
|
+
if (!waitQueueMember[kCancelled]) {
|
|
1046
|
+
waitQueueMember.callback(err);
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
function processWaitQueue(topology) {
|
|
1052
|
+
if (topology.s.state === STATE_CLOSED) {
|
|
1053
|
+
drainWaitQueue(topology[kWaitQueue], new MongoError('Topology is closed, please connect'));
|
|
1054
|
+
return;
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
const isSharded = topology.description.type === TopologyType.Sharded;
|
|
1058
|
+
const serverDescriptions = Array.from(topology.description.servers.values());
|
|
1059
|
+
for (let i = 0; i < topology[kWaitQueue].length; ++i) {
|
|
1060
|
+
const waitQueueMember = topology[kWaitQueue].shift();
|
|
1061
|
+
if (waitQueueMember[kCancelled]) {
|
|
1062
|
+
continue;
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
let selectedDescriptions;
|
|
1066
|
+
try {
|
|
1067
|
+
const serverSelector = waitQueueMember.serverSelector;
|
|
1068
|
+
selectedDescriptions = serverSelector
|
|
1069
|
+
? serverSelector(topology.description, serverDescriptions)
|
|
1070
|
+
: serverDescriptions;
|
|
1071
|
+
} catch (e) {
|
|
1072
|
+
clearTimeout(waitQueueMember.timer);
|
|
1073
|
+
waitQueueMember.callback(e);
|
|
1074
|
+
break;
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
if (selectedDescriptions.length === 0) {
|
|
1078
|
+
topology[kWaitQueue].push(waitQueueMember);
|
|
1079
|
+
break;
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
const selectedServerDescription = randomSelection(selectedDescriptions);
|
|
1083
|
+
const selectedServer = topology.s.servers.get(selectedServerDescription.address);
|
|
1084
|
+
const transaction = waitQueueMember.transaction;
|
|
1085
|
+
if (isSharded && transaction && transaction.isActive) {
|
|
1086
|
+
transaction.pinServer(selectedServer);
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
clearTimeout(waitQueueMember.timer);
|
|
1090
|
+
waitQueueMember.callback(undefined, selectedServer);
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
if (topology[kWaitQueue].length > 0) {
|
|
1094
|
+
// ensure all server monitors attempt monitoring soon
|
|
1095
|
+
topology.s.servers.forEach(server => process.nextTick(() => server.requestCheck()));
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1016
1099
|
/**
|
|
1017
1100
|
* A server opening SDAM monitoring event
|
|
1018
1101
|
*
|