mongodb 3.2.5 → 3.3.0-beta2
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 +0 -10
- package/index.js +4 -4
- package/lib/admin.js +56 -56
- package/lib/aggregation_cursor.js +7 -3
- package/lib/bulk/common.js +18 -13
- package/lib/change_stream.js +196 -89
- package/lib/collection.js +217 -169
- package/lib/command_cursor.js +17 -7
- package/lib/core/auth/auth_provider.js +158 -0
- package/lib/core/auth/defaultAuthProviders.js +29 -0
- package/lib/core/auth/gssapi.js +241 -0
- package/lib/core/auth/mongo_credentials.js +81 -0
- package/lib/core/auth/mongocr.js +51 -0
- package/lib/core/auth/plain.js +35 -0
- package/lib/core/auth/scram.js +293 -0
- package/lib/core/auth/sspi.js +131 -0
- package/lib/core/auth/x509.js +26 -0
- package/lib/core/connection/apm.js +236 -0
- package/lib/core/connection/command_result.js +36 -0
- package/lib/core/connection/commands.js +507 -0
- package/lib/core/connection/connect.js +370 -0
- package/lib/core/connection/connection.js +624 -0
- package/lib/core/connection/logger.js +246 -0
- package/lib/core/connection/msg.js +219 -0
- package/lib/core/connection/pool.js +1285 -0
- package/lib/core/connection/utils.js +57 -0
- package/lib/core/cursor.js +752 -0
- package/lib/core/error.js +186 -0
- package/lib/core/index.js +50 -0
- package/lib/core/sdam/monitoring.js +228 -0
- package/lib/core/sdam/server.js +467 -0
- package/lib/core/sdam/server_description.js +163 -0
- package/lib/core/sdam/server_selectors.js +244 -0
- package/lib/core/sdam/srv_polling.js +135 -0
- package/lib/core/sdam/topology.js +1151 -0
- package/lib/core/sdam/topology_description.js +408 -0
- package/lib/core/sessions.js +711 -0
- package/lib/core/tools/smoke_plugin.js +61 -0
- package/lib/core/topologies/mongos.js +1337 -0
- package/lib/core/topologies/read_preference.js +202 -0
- package/lib/core/topologies/replset.js +1507 -0
- package/lib/core/topologies/replset_state.js +1121 -0
- package/lib/core/topologies/server.js +984 -0
- package/lib/core/topologies/shared.js +453 -0
- package/lib/core/transactions.js +167 -0
- package/lib/core/uri_parser.js +631 -0
- package/lib/core/utils.js +165 -0
- package/lib/core/wireprotocol/command.js +170 -0
- package/lib/core/wireprotocol/compression.js +73 -0
- package/lib/core/wireprotocol/constants.js +13 -0
- package/lib/core/wireprotocol/get_more.js +86 -0
- package/lib/core/wireprotocol/index.js +18 -0
- package/lib/core/wireprotocol/kill_cursors.js +70 -0
- package/lib/core/wireprotocol/query.js +224 -0
- package/lib/core/wireprotocol/shared.js +115 -0
- package/lib/core/wireprotocol/write_command.js +50 -0
- package/lib/cursor.js +40 -46
- package/lib/db.js +141 -95
- package/lib/dynamic_loaders.js +32 -0
- package/lib/error.js +12 -10
- package/lib/gridfs/chunk.js +2 -2
- package/lib/gridfs/grid_store.js +31 -25
- package/lib/gridfs-stream/index.js +4 -4
- package/lib/gridfs-stream/upload.js +1 -1
- package/lib/mongo_client.js +37 -15
- package/lib/operations/add_user.js +96 -0
- package/lib/operations/aggregate.js +24 -13
- package/lib/operations/aggregate_operation.js +127 -0
- package/lib/operations/bulk_write.js +104 -0
- package/lib/operations/close.js +47 -0
- package/lib/operations/collection_ops.js +28 -287
- package/lib/operations/collections.js +55 -0
- package/lib/operations/command.js +120 -0
- package/lib/operations/command_v2.js +43 -0
- package/lib/operations/common_functions.js +372 -0
- package/lib/operations/{mongo_client_ops.js → connect.js} +185 -157
- package/lib/operations/count.js +72 -0
- package/lib/operations/count_documents.js +46 -0
- package/lib/operations/create_collection.js +118 -0
- package/lib/operations/create_index.js +92 -0
- package/lib/operations/create_indexes.js +61 -0
- package/lib/operations/cursor_ops.js +3 -4
- package/lib/operations/db_ops.js +15 -12
- package/lib/operations/delete_many.js +25 -0
- package/lib/operations/delete_one.js +25 -0
- package/lib/operations/distinct.js +85 -0
- package/lib/operations/drop.js +53 -0
- package/lib/operations/drop_index.js +42 -0
- package/lib/operations/drop_indexes.js +23 -0
- package/lib/operations/estimated_document_count.js +33 -0
- package/lib/operations/execute_db_admin_command.js +34 -0
- package/lib/operations/execute_operation.js +165 -0
- package/lib/operations/explain.js +23 -0
- package/lib/operations/find_and_modify.js +98 -0
- package/lib/operations/find_one.js +33 -0
- package/lib/operations/find_one_and_delete.js +16 -0
- package/lib/operations/find_one_and_replace.js +18 -0
- package/lib/operations/find_one_and_update.js +19 -0
- package/lib/operations/geo_haystack_search.js +79 -0
- package/lib/operations/has_next.js +40 -0
- package/lib/operations/index_exists.js +39 -0
- package/lib/operations/index_information.js +23 -0
- package/lib/operations/indexes.js +22 -0
- package/lib/operations/insert_many.js +63 -0
- package/lib/operations/insert_one.js +75 -0
- package/lib/operations/is_capped.js +19 -0
- package/lib/operations/list_indexes.js +66 -0
- package/lib/operations/map_reduce.js +189 -0
- package/lib/operations/next.js +32 -0
- package/lib/operations/operation.js +63 -0
- package/lib/operations/options_operation.js +32 -0
- package/lib/operations/profiling_level.js +31 -0
- package/lib/operations/re_index.js +28 -0
- package/lib/operations/remove_user.js +52 -0
- package/lib/operations/rename.js +61 -0
- package/lib/operations/replace_one.js +47 -0
- package/lib/operations/set_profiling_level.js +48 -0
- package/lib/operations/stats.js +45 -0
- package/lib/operations/to_array.js +68 -0
- package/lib/operations/update_many.js +29 -0
- package/lib/operations/update_one.js +44 -0
- package/lib/operations/validate_collection.js +40 -0
- package/lib/read_concern.js +55 -0
- package/lib/topologies/mongos.js +3 -3
- package/lib/topologies/native_topology.js +22 -2
- package/lib/topologies/replset.js +3 -3
- package/lib/topologies/server.js +4 -4
- package/lib/topologies/topology_base.js +6 -6
- package/lib/url_parser.js +4 -3
- package/lib/utils.js +46 -59
- package/lib/write_concern.js +66 -0
- package/package.json +15 -6
- package/lib/.DS_Store +0 -0
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const ServerType = require('./server_description').ServerType;
|
|
3
|
+
const ServerDescription = require('./server_description').ServerDescription;
|
|
4
|
+
const WIRE_CONSTANTS = require('../wireprotocol/constants');
|
|
5
|
+
|
|
6
|
+
// contstants related to compatability checks
|
|
7
|
+
const MIN_SUPPORTED_SERVER_VERSION = WIRE_CONSTANTS.MIN_SUPPORTED_SERVER_VERSION;
|
|
8
|
+
const MAX_SUPPORTED_SERVER_VERSION = WIRE_CONSTANTS.MAX_SUPPORTED_SERVER_VERSION;
|
|
9
|
+
const MIN_SUPPORTED_WIRE_VERSION = WIRE_CONSTANTS.MIN_SUPPORTED_WIRE_VERSION;
|
|
10
|
+
const MAX_SUPPORTED_WIRE_VERSION = WIRE_CONSTANTS.MAX_SUPPORTED_WIRE_VERSION;
|
|
11
|
+
|
|
12
|
+
// An enumeration of topology types we know about
|
|
13
|
+
const TopologyType = {
|
|
14
|
+
Single: 'Single',
|
|
15
|
+
ReplicaSetNoPrimary: 'ReplicaSetNoPrimary',
|
|
16
|
+
ReplicaSetWithPrimary: 'ReplicaSetWithPrimary',
|
|
17
|
+
Sharded: 'Sharded',
|
|
18
|
+
Unknown: 'Unknown'
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
// Representation of a deployment of servers
|
|
22
|
+
class TopologyDescription {
|
|
23
|
+
/**
|
|
24
|
+
* Create a TopologyDescription
|
|
25
|
+
*
|
|
26
|
+
* @param {string} topologyType
|
|
27
|
+
* @param {Map<string, ServerDescription>} serverDescriptions the a map of address to ServerDescription
|
|
28
|
+
* @param {string} setName
|
|
29
|
+
* @param {number} maxSetVersion
|
|
30
|
+
* @param {ObjectId} maxElectionId
|
|
31
|
+
*/
|
|
32
|
+
constructor(
|
|
33
|
+
topologyType,
|
|
34
|
+
serverDescriptions,
|
|
35
|
+
setName,
|
|
36
|
+
maxSetVersion,
|
|
37
|
+
maxElectionId,
|
|
38
|
+
commonWireVersion,
|
|
39
|
+
options,
|
|
40
|
+
error
|
|
41
|
+
) {
|
|
42
|
+
options = options || {};
|
|
43
|
+
|
|
44
|
+
// TODO: consider assigning all these values to a temporary value `s` which
|
|
45
|
+
// we use `Object.freeze` on, ensuring the internal state of this type
|
|
46
|
+
// is immutable.
|
|
47
|
+
this.type = topologyType || TopologyType.Unknown;
|
|
48
|
+
this.setName = setName || null;
|
|
49
|
+
this.maxSetVersion = maxSetVersion || null;
|
|
50
|
+
this.maxElectionId = maxElectionId || null;
|
|
51
|
+
this.servers = serverDescriptions || new Map();
|
|
52
|
+
this.stale = false;
|
|
53
|
+
this.compatible = true;
|
|
54
|
+
this.compatibilityError = null;
|
|
55
|
+
this.logicalSessionTimeoutMinutes = null;
|
|
56
|
+
this.heartbeatFrequencyMS = options.heartbeatFrequencyMS || 0;
|
|
57
|
+
this.localThresholdMS = options.localThresholdMS || 0;
|
|
58
|
+
this.options = options;
|
|
59
|
+
this.error = error;
|
|
60
|
+
this.commonWireVersion = commonWireVersion || null;
|
|
61
|
+
|
|
62
|
+
// determine server compatibility
|
|
63
|
+
for (const serverDescription of this.servers.values()) {
|
|
64
|
+
if (serverDescription.type === ServerType.Unknown) continue;
|
|
65
|
+
|
|
66
|
+
if (serverDescription.minWireVersion > MAX_SUPPORTED_WIRE_VERSION) {
|
|
67
|
+
this.compatible = false;
|
|
68
|
+
this.compatibilityError = `Server at ${serverDescription.address} requires wire version ${
|
|
69
|
+
serverDescription.minWireVersion
|
|
70
|
+
}, but this version of the driver only supports up to ${MAX_SUPPORTED_WIRE_VERSION} (MongoDB ${MAX_SUPPORTED_SERVER_VERSION})`;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (serverDescription.maxWireVersion < MIN_SUPPORTED_WIRE_VERSION) {
|
|
74
|
+
this.compatible = false;
|
|
75
|
+
this.compatibilityError = `Server at ${serverDescription.address} reports wire version ${
|
|
76
|
+
serverDescription.maxWireVersion
|
|
77
|
+
}, but this version of the driver requires at least ${MIN_SUPPORTED_WIRE_VERSION} (MongoDB ${MIN_SUPPORTED_SERVER_VERSION}).`;
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Whenever a client updates the TopologyDescription from an ismaster response, it MUST set
|
|
83
|
+
// TopologyDescription.logicalSessionTimeoutMinutes to the smallest logicalSessionTimeoutMinutes
|
|
84
|
+
// value among ServerDescriptions of all data-bearing server types. If any have a null
|
|
85
|
+
// logicalSessionTimeoutMinutes, then TopologyDescription.logicalSessionTimeoutMinutes MUST be
|
|
86
|
+
// set to null.
|
|
87
|
+
const readableServers = Array.from(this.servers.values()).filter(s => s.isReadable);
|
|
88
|
+
this.logicalSessionTimeoutMinutes = readableServers.reduce((result, server) => {
|
|
89
|
+
if (server.logicalSessionTimeoutMinutes == null) return null;
|
|
90
|
+
if (result == null) return server.logicalSessionTimeoutMinutes;
|
|
91
|
+
return Math.min(result, server.logicalSessionTimeoutMinutes);
|
|
92
|
+
}, null);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Returns a new TopologyDescription based on the SrvPollingEvent
|
|
97
|
+
* @param {SrvPollingEvent} ev The event
|
|
98
|
+
*/
|
|
99
|
+
updateFromSrvPollingEvent(ev) {
|
|
100
|
+
const newAddresses = ev.addresses();
|
|
101
|
+
const serverDescriptions = new Map(this.servers);
|
|
102
|
+
for (const server of this.servers) {
|
|
103
|
+
if (newAddresses.has(server[0])) {
|
|
104
|
+
newAddresses.delete(server[0]);
|
|
105
|
+
} else {
|
|
106
|
+
serverDescriptions.delete(server[0]);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (serverDescriptions.size === this.servers.size && newAddresses.size === 0) {
|
|
111
|
+
return this;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
for (const address of newAddresses) {
|
|
115
|
+
serverDescriptions.set(address, new ServerDescription(address));
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return new TopologyDescription(
|
|
119
|
+
this.type,
|
|
120
|
+
serverDescriptions,
|
|
121
|
+
this.setName,
|
|
122
|
+
this.maxSetVersion,
|
|
123
|
+
this.maxElectionId,
|
|
124
|
+
this.commonWireVersion,
|
|
125
|
+
this.options,
|
|
126
|
+
null
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Returns a copy of this description updated with a given ServerDescription
|
|
132
|
+
*
|
|
133
|
+
* @param {ServerDescription} serverDescription
|
|
134
|
+
*/
|
|
135
|
+
update(serverDescription) {
|
|
136
|
+
const address = serverDescription.address;
|
|
137
|
+
// NOTE: there are a number of prime targets for refactoring here
|
|
138
|
+
// once we support destructuring assignments
|
|
139
|
+
|
|
140
|
+
// potentially mutated values
|
|
141
|
+
let topologyType = this.type;
|
|
142
|
+
let setName = this.setName;
|
|
143
|
+
let maxSetVersion = this.maxSetVersion;
|
|
144
|
+
let maxElectionId = this.maxElectionId;
|
|
145
|
+
let commonWireVersion = this.commonWireVersion;
|
|
146
|
+
let error = serverDescription.error || null;
|
|
147
|
+
|
|
148
|
+
const serverType = serverDescription.type;
|
|
149
|
+
let serverDescriptions = new Map(this.servers);
|
|
150
|
+
|
|
151
|
+
// update common wire version
|
|
152
|
+
if (serverDescription.maxWireVersion !== 0) {
|
|
153
|
+
if (commonWireVersion == null) {
|
|
154
|
+
commonWireVersion = serverDescription.maxWireVersion;
|
|
155
|
+
} else {
|
|
156
|
+
commonWireVersion = Math.min(commonWireVersion, serverDescription.maxWireVersion);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// update the actual server description
|
|
161
|
+
serverDescriptions.set(address, serverDescription);
|
|
162
|
+
|
|
163
|
+
if (topologyType === TopologyType.Single) {
|
|
164
|
+
// once we are defined as single, that never changes
|
|
165
|
+
return new TopologyDescription(
|
|
166
|
+
TopologyType.Single,
|
|
167
|
+
serverDescriptions,
|
|
168
|
+
setName,
|
|
169
|
+
maxSetVersion,
|
|
170
|
+
maxElectionId,
|
|
171
|
+
commonWireVersion,
|
|
172
|
+
this.options,
|
|
173
|
+
error
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (topologyType === TopologyType.Unknown) {
|
|
178
|
+
if (serverType === ServerType.Standalone) {
|
|
179
|
+
serverDescriptions.delete(address);
|
|
180
|
+
} else {
|
|
181
|
+
topologyType = topologyTypeForServerType(serverType);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (topologyType === TopologyType.Sharded) {
|
|
186
|
+
if ([ServerType.Mongos, ServerType.Unknown].indexOf(serverType) === -1) {
|
|
187
|
+
serverDescriptions.delete(address);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (topologyType === TopologyType.ReplicaSetNoPrimary) {
|
|
192
|
+
if ([ServerType.Mongos, ServerType.Unknown].indexOf(serverType) >= 0) {
|
|
193
|
+
serverDescriptions.delete(address);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (serverType === ServerType.RSPrimary) {
|
|
197
|
+
const result = updateRsFromPrimary(
|
|
198
|
+
serverDescriptions,
|
|
199
|
+
setName,
|
|
200
|
+
serverDescription,
|
|
201
|
+
maxSetVersion,
|
|
202
|
+
maxElectionId
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
(topologyType = result[0]),
|
|
206
|
+
(setName = result[1]),
|
|
207
|
+
(maxSetVersion = result[2]),
|
|
208
|
+
(maxElectionId = result[3]);
|
|
209
|
+
} else if (
|
|
210
|
+
[ServerType.RSSecondary, ServerType.RSArbiter, ServerType.RSOther].indexOf(serverType) >= 0
|
|
211
|
+
) {
|
|
212
|
+
const result = updateRsNoPrimaryFromMember(serverDescriptions, setName, serverDescription);
|
|
213
|
+
(topologyType = result[0]), (setName = result[1]);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (topologyType === TopologyType.ReplicaSetWithPrimary) {
|
|
218
|
+
if ([ServerType.Standalone, ServerType.Mongos].indexOf(serverType) >= 0) {
|
|
219
|
+
serverDescriptions.delete(address);
|
|
220
|
+
topologyType = checkHasPrimary(serverDescriptions);
|
|
221
|
+
} else if (serverType === ServerType.RSPrimary) {
|
|
222
|
+
const result = updateRsFromPrimary(
|
|
223
|
+
serverDescriptions,
|
|
224
|
+
setName,
|
|
225
|
+
serverDescription,
|
|
226
|
+
maxSetVersion,
|
|
227
|
+
maxElectionId
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
(topologyType = result[0]),
|
|
231
|
+
(setName = result[1]),
|
|
232
|
+
(maxSetVersion = result[2]),
|
|
233
|
+
(maxElectionId = result[3]);
|
|
234
|
+
} else if (
|
|
235
|
+
[ServerType.RSSecondary, ServerType.RSArbiter, ServerType.RSOther].indexOf(serverType) >= 0
|
|
236
|
+
) {
|
|
237
|
+
topologyType = updateRsWithPrimaryFromMember(
|
|
238
|
+
serverDescriptions,
|
|
239
|
+
setName,
|
|
240
|
+
serverDescription
|
|
241
|
+
);
|
|
242
|
+
} else {
|
|
243
|
+
topologyType = checkHasPrimary(serverDescriptions);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
return new TopologyDescription(
|
|
248
|
+
topologyType,
|
|
249
|
+
serverDescriptions,
|
|
250
|
+
setName,
|
|
251
|
+
maxSetVersion,
|
|
252
|
+
maxElectionId,
|
|
253
|
+
commonWireVersion,
|
|
254
|
+
this.options,
|
|
255
|
+
error
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Determines if the topology description has any known servers
|
|
261
|
+
*/
|
|
262
|
+
get hasKnownServers() {
|
|
263
|
+
return Array.from(this.servers.values()).some(sd => sd.type !== ServerDescription.Unknown);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Determines if this topology description has a data-bearing server available.
|
|
268
|
+
*/
|
|
269
|
+
get hasDataBearingServers() {
|
|
270
|
+
return Array.from(this.servers.values()).some(sd => sd.isDataBearing);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Determines if the topology has a definition for the provided address
|
|
275
|
+
*
|
|
276
|
+
* @param {String} address
|
|
277
|
+
* @return {Boolean} Whether the topology knows about this server
|
|
278
|
+
*/
|
|
279
|
+
hasServer(address) {
|
|
280
|
+
return this.servers.has(address);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
function topologyTypeForServerType(serverType) {
|
|
285
|
+
if (serverType === ServerType.Mongos) return TopologyType.Sharded;
|
|
286
|
+
if (serverType === ServerType.RSPrimary) return TopologyType.ReplicaSetWithPrimary;
|
|
287
|
+
return TopologyType.ReplicaSetNoPrimary;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
function updateRsFromPrimary(
|
|
291
|
+
serverDescriptions,
|
|
292
|
+
setName,
|
|
293
|
+
serverDescription,
|
|
294
|
+
maxSetVersion,
|
|
295
|
+
maxElectionId
|
|
296
|
+
) {
|
|
297
|
+
setName = setName || serverDescription.setName;
|
|
298
|
+
if (setName !== serverDescription.setName) {
|
|
299
|
+
serverDescriptions.delete(serverDescription.address);
|
|
300
|
+
return [checkHasPrimary(serverDescriptions), setName, maxSetVersion, maxElectionId];
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
const electionIdOID = serverDescription.electionId ? serverDescription.electionId.$oid : null;
|
|
304
|
+
const maxElectionIdOID = maxElectionId ? maxElectionId.$oid : null;
|
|
305
|
+
if (serverDescription.setVersion != null && electionIdOID != null) {
|
|
306
|
+
if (maxSetVersion != null && maxElectionIdOID != null) {
|
|
307
|
+
if (maxSetVersion > serverDescription.setVersion || maxElectionIdOID > electionIdOID) {
|
|
308
|
+
// this primary is stale, we must remove it
|
|
309
|
+
serverDescriptions.set(
|
|
310
|
+
serverDescription.address,
|
|
311
|
+
new ServerDescription(serverDescription.address)
|
|
312
|
+
);
|
|
313
|
+
|
|
314
|
+
return [checkHasPrimary(serverDescriptions), setName, maxSetVersion, maxElectionId];
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
maxElectionId = serverDescription.electionId;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
if (
|
|
322
|
+
serverDescription.setVersion != null &&
|
|
323
|
+
(maxSetVersion == null || serverDescription.setVersion > maxSetVersion)
|
|
324
|
+
) {
|
|
325
|
+
maxSetVersion = serverDescription.setVersion;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// We've heard from the primary. Is it the same primary as before?
|
|
329
|
+
for (const address of serverDescriptions.keys()) {
|
|
330
|
+
const server = serverDescriptions.get(address);
|
|
331
|
+
|
|
332
|
+
if (server.type === ServerType.RSPrimary && server.address !== serverDescription.address) {
|
|
333
|
+
// Reset old primary's type to Unknown.
|
|
334
|
+
serverDescriptions.set(address, new ServerDescription(server.address));
|
|
335
|
+
|
|
336
|
+
// There can only be one primary
|
|
337
|
+
break;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Discover new hosts from this primary's response.
|
|
342
|
+
serverDescription.allHosts.forEach(address => {
|
|
343
|
+
if (!serverDescriptions.has(address)) {
|
|
344
|
+
serverDescriptions.set(address, new ServerDescription(address));
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
// Remove hosts not in the response.
|
|
349
|
+
const currentAddresses = Array.from(serverDescriptions.keys());
|
|
350
|
+
const responseAddresses = serverDescription.allHosts;
|
|
351
|
+
currentAddresses.filter(addr => responseAddresses.indexOf(addr) === -1).forEach(address => {
|
|
352
|
+
serverDescriptions.delete(address);
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
return [checkHasPrimary(serverDescriptions), setName, maxSetVersion, maxElectionId];
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
function updateRsWithPrimaryFromMember(serverDescriptions, setName, serverDescription) {
|
|
359
|
+
if (setName == null) {
|
|
360
|
+
throw new TypeError('setName is required');
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
if (
|
|
364
|
+
setName !== serverDescription.setName ||
|
|
365
|
+
(serverDescription.me && serverDescription.address !== serverDescription.me)
|
|
366
|
+
) {
|
|
367
|
+
serverDescriptions.delete(serverDescription.address);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
return checkHasPrimary(serverDescriptions);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
function updateRsNoPrimaryFromMember(serverDescriptions, setName, serverDescription) {
|
|
374
|
+
let topologyType = TopologyType.ReplicaSetNoPrimary;
|
|
375
|
+
|
|
376
|
+
setName = setName || serverDescription.setName;
|
|
377
|
+
if (setName !== serverDescription.setName) {
|
|
378
|
+
serverDescriptions.delete(serverDescription.address);
|
|
379
|
+
return [topologyType, setName];
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
serverDescription.allHosts.forEach(address => {
|
|
383
|
+
if (!serverDescriptions.has(address)) {
|
|
384
|
+
serverDescriptions.set(address, new ServerDescription(address));
|
|
385
|
+
}
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
if (serverDescription.me && serverDescription.address !== serverDescription.me) {
|
|
389
|
+
serverDescriptions.delete(serverDescription.address);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
return [topologyType, setName];
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
function checkHasPrimary(serverDescriptions) {
|
|
396
|
+
for (const addr of serverDescriptions.keys()) {
|
|
397
|
+
if (serverDescriptions.get(addr).type === ServerType.RSPrimary) {
|
|
398
|
+
return TopologyType.ReplicaSetWithPrimary;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
return TopologyType.ReplicaSetNoPrimary;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
module.exports = {
|
|
406
|
+
TopologyType,
|
|
407
|
+
TopologyDescription
|
|
408
|
+
};
|