@resolveio/server-lib 20.13.1 → 20.13.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/managers/mongo.manager.d.ts +1 -1
- package/managers/mongo.manager.js +5 -1
- package/managers/mongo.manager.js.map +1 -1
- package/managers/subscription.manager.d.ts +11 -0
- package/managers/subscription.manager.js +194 -23
- package/managers/subscription.manager.js.map +1 -1
- package/package.json +1 -1
- package/resolveio-server-app.d.ts +3 -3
- package/resolveio-server-app.js +9 -9
- package/resolveio-server-app.js.map +1 -1
- package/server-app.d.ts +0 -1
- package/server-app.js +1 -2
- package/server-app.js.map +1 -1
|
@@ -13,6 +13,10 @@ export declare class SubscriptionManager {
|
|
|
13
13
|
private _mongoQueue;
|
|
14
14
|
private _mongoQueueId;
|
|
15
15
|
private _oplog$;
|
|
16
|
+
private _oplogMode;
|
|
17
|
+
private _useLocalOplog;
|
|
18
|
+
private _localOplogResyncIntervalMs;
|
|
19
|
+
private _localOplogResyncTimer;
|
|
16
20
|
private _nodeCache;
|
|
17
21
|
private _cacheId;
|
|
18
22
|
private _heapSize;
|
|
@@ -69,6 +73,13 @@ export declare class SubscriptionManager {
|
|
|
69
73
|
getActiveSubscriptions(): ActiveSubscriptionModel[];
|
|
70
74
|
private getPublicationCollections;
|
|
71
75
|
private getWatchedDatabases;
|
|
76
|
+
private resolveOplogMode;
|
|
77
|
+
private resolveLocalOplogResyncIntervalMs;
|
|
78
|
+
private parsePositiveNumber;
|
|
79
|
+
private isChangeStreamUnsupported;
|
|
80
|
+
private enableLocalOplogFallback;
|
|
81
|
+
getUseLocalOplog(): boolean;
|
|
82
|
+
notifyLocalOplog(collection: string, type?: string): void;
|
|
72
83
|
private getResumeTokenDocId;
|
|
73
84
|
private loadResumeToken;
|
|
74
85
|
private saveResumeToken;
|
|
@@ -124,6 +124,10 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
124
124
|
this._lastRouteBySocket = new Map();
|
|
125
125
|
this._mongoQueue = [];
|
|
126
126
|
this._mongoQueueId = 0;
|
|
127
|
+
this._oplogMode = 'auto';
|
|
128
|
+
this._useLocalOplog = false;
|
|
129
|
+
this._localOplogResyncIntervalMs = 0;
|
|
130
|
+
this._localOplogResyncTimer = null;
|
|
127
131
|
this._cacheId = 1;
|
|
128
132
|
this._heapSize = resolveHeapLimitBytes();
|
|
129
133
|
this._enableDebug = false;
|
|
@@ -204,6 +208,8 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
204
208
|
// }, 10000);
|
|
205
209
|
this.serverConfig = serverConfig;
|
|
206
210
|
this._wss = wss;
|
|
211
|
+
this._oplogMode = this.resolveOplogMode();
|
|
212
|
+
this._localOplogResyncIntervalMs = this.resolveLocalOplogResyncIntervalMs();
|
|
207
213
|
// Publications
|
|
208
214
|
(0, super_admin_1.loadSuperAdminPublications)(this);
|
|
209
215
|
(0, app_status_1.loadAppStatusPublications)(this);
|
|
@@ -218,12 +224,19 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
218
224
|
(0, user_groups_1.loadUserGroupPublications)(this);
|
|
219
225
|
(0, user_guides_1.loadUserGuidePublications)(this);
|
|
220
226
|
(0, report_builder_dashboard_builders_1.loadReportBuilderDashboardBuilderPublications)(this);
|
|
221
|
-
return [
|
|
227
|
+
if (!(this._oplogMode === 'local')) return [3 /*break*/, 2];
|
|
228
|
+
return [4 /*yield*/, this.enableLocalOplogFallback('config')];
|
|
222
229
|
case 1:
|
|
230
|
+
_a.sent();
|
|
231
|
+
return [3 /*break*/, 5];
|
|
232
|
+
case 2: return [4 /*yield*/, this.loadResumeToken()];
|
|
233
|
+
case 3:
|
|
223
234
|
resumeToken = _a.sent();
|
|
224
235
|
return [4 /*yield*/, this.tailOpLog(resumeToken || undefined)];
|
|
225
|
-
case
|
|
236
|
+
case 4:
|
|
226
237
|
_a.sent();
|
|
238
|
+
_a.label = 5;
|
|
239
|
+
case 5:
|
|
227
240
|
setInterval(function () {
|
|
228
241
|
_this._oplogRetryCount = 0;
|
|
229
242
|
}, 15000);
|
|
@@ -330,10 +343,10 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
330
343
|
});
|
|
331
344
|
}); }, 30000);
|
|
332
345
|
return [4 /*yield*/, flag_collection_1.Flags.findOne({ type: 'Enable Debug' })];
|
|
333
|
-
case
|
|
346
|
+
case 6:
|
|
334
347
|
flag = _a.sent();
|
|
335
348
|
return [4 /*yield*/, flag_collection_1.Flags.findOne({ type: 'Enable Dependency Debug' })];
|
|
336
|
-
case
|
|
349
|
+
case 7:
|
|
337
350
|
dependencyFlag = _a.sent();
|
|
338
351
|
if (flag && flag.value) {
|
|
339
352
|
this._enableDebug = true;
|
|
@@ -430,7 +443,7 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
430
443
|
}
|
|
431
444
|
events = queued.events;
|
|
432
445
|
// Original invalidation logic
|
|
433
|
-
resolveio_server_app_1.ResolveIOServer.getMongoManager().invalidateQueryCache(collection);
|
|
446
|
+
resolveio_server_app_1.ResolveIOServer.getMongoManager().invalidateQueryCache(collection, true);
|
|
434
447
|
collSubs = this._subscriptions.filter(function (sub) { return _this.subscriptionReferencesCollection(sub, collection); });
|
|
435
448
|
_f.label = 1;
|
|
436
449
|
case 1:
|
|
@@ -937,6 +950,128 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
937
950
|
var mainDb = config && typeof config['DATABASE'] === 'string' ? config['DATABASE'] : '';
|
|
938
951
|
return mainDb ? [mainDb] : [];
|
|
939
952
|
};
|
|
953
|
+
SubscriptionManager.prototype.resolveOplogMode = function () {
|
|
954
|
+
var config = this.serverConfig || resolveio_server_app_1.ResolveIOServer.getServerConfig() || {};
|
|
955
|
+
var raw = process.env.SUBSCRIPTION_OPLOG_MODE || process.env.OPLOG_MODE || config['SUBSCRIPTION_OPLOG_MODE'] || config['OPLOG_MODE'];
|
|
956
|
+
if (typeof raw !== 'string' || !raw.trim()) {
|
|
957
|
+
return 'auto';
|
|
958
|
+
}
|
|
959
|
+
var normalized = raw.trim().toLowerCase();
|
|
960
|
+
if (['local', 'single', 'standalone', 'fallback', 'poll'].includes(normalized)) {
|
|
961
|
+
return 'local';
|
|
962
|
+
}
|
|
963
|
+
if (['change-stream', 'changestream', 'oplog', 'replica', 'replicaset', 'rs'].includes(normalized)) {
|
|
964
|
+
return 'change-stream';
|
|
965
|
+
}
|
|
966
|
+
return 'auto';
|
|
967
|
+
};
|
|
968
|
+
SubscriptionManager.prototype.resolveLocalOplogResyncIntervalMs = function () {
|
|
969
|
+
var config = this.serverConfig || resolveio_server_app_1.ResolveIOServer.getServerConfig() || {};
|
|
970
|
+
var raw = process.env.OPLOG_FALLBACK_RESYNC_MS
|
|
971
|
+
|| process.env.SUBSCRIPTION_OPLOG_RESYNC_MS
|
|
972
|
+
|| config['OPLOG_FALLBACK_RESYNC_MS']
|
|
973
|
+
|| config['SUBSCRIPTION_OPLOG_RESYNC_MS'];
|
|
974
|
+
return this.parsePositiveNumber(raw);
|
|
975
|
+
};
|
|
976
|
+
SubscriptionManager.prototype.parsePositiveNumber = function (value) {
|
|
977
|
+
if (typeof value === 'number' && Number.isFinite(value) && value > 0) {
|
|
978
|
+
return value;
|
|
979
|
+
}
|
|
980
|
+
if (typeof value === 'string' && value.trim().length) {
|
|
981
|
+
var parsed = parseInt(value, 10);
|
|
982
|
+
if (Number.isFinite(parsed) && parsed > 0) {
|
|
983
|
+
return parsed;
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
return 0;
|
|
987
|
+
};
|
|
988
|
+
SubscriptionManager.prototype.isChangeStreamUnsupported = function (error) {
|
|
989
|
+
var code = typeof (error === null || error === void 0 ? void 0 : error.code) === 'number' ? error.code : null;
|
|
990
|
+
var codeName = typeof (error === null || error === void 0 ? void 0 : error.codeName) === 'string' ? error.codeName.toLowerCase() : '';
|
|
991
|
+
var message = typeof (error === null || error === void 0 ? void 0 : error.message) === 'string' ? error.message.toLowerCase() : '';
|
|
992
|
+
if (code === 40573) {
|
|
993
|
+
return true;
|
|
994
|
+
}
|
|
995
|
+
if (codeName && codeName.includes('changestream')) {
|
|
996
|
+
return true;
|
|
997
|
+
}
|
|
998
|
+
if (message.includes('change stream') && message.includes('replica')) {
|
|
999
|
+
return true;
|
|
1000
|
+
}
|
|
1001
|
+
if (message.includes('change stream') && message.includes('not supported')) {
|
|
1002
|
+
return true;
|
|
1003
|
+
}
|
|
1004
|
+
return false;
|
|
1005
|
+
};
|
|
1006
|
+
SubscriptionManager.prototype.enableLocalOplogFallback = function (reason, error) {
|
|
1007
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
1008
|
+
var _a, message;
|
|
1009
|
+
var _this = this;
|
|
1010
|
+
return __generator(this, function (_b) {
|
|
1011
|
+
switch (_b.label) {
|
|
1012
|
+
case 0:
|
|
1013
|
+
if (this._useLocalOplog) {
|
|
1014
|
+
return [2 /*return*/];
|
|
1015
|
+
}
|
|
1016
|
+
this._useLocalOplog = true;
|
|
1017
|
+
this._oplogMode = 'local';
|
|
1018
|
+
this._oplogRetryCount = 0;
|
|
1019
|
+
if (!(this._oplog$ && !this._oplog$.closed)) return [3 /*break*/, 5];
|
|
1020
|
+
_b.label = 1;
|
|
1021
|
+
case 1:
|
|
1022
|
+
_b.trys.push([1, 3, , 4]);
|
|
1023
|
+
this._oplog$.removeAllListeners();
|
|
1024
|
+
return [4 /*yield*/, this._oplog$.close()];
|
|
1025
|
+
case 2:
|
|
1026
|
+
_b.sent();
|
|
1027
|
+
return [3 /*break*/, 4];
|
|
1028
|
+
case 3:
|
|
1029
|
+
_a = _b.sent();
|
|
1030
|
+
return [3 /*break*/, 4];
|
|
1031
|
+
case 4:
|
|
1032
|
+
this._oplog$ = null;
|
|
1033
|
+
_b.label = 5;
|
|
1034
|
+
case 5:
|
|
1035
|
+
message = typeof (error === null || error === void 0 ? void 0 : error.message) === 'string' ? error.message : '';
|
|
1036
|
+
console.log(new Date(), 'oplog fallback enabled', reason, message ? "(".concat(message, ")") : '');
|
|
1037
|
+
this.queueFullResync('oplog-fallback-enabled');
|
|
1038
|
+
if (this._localOplogResyncIntervalMs > 0 && !this._localOplogResyncTimer) {
|
|
1039
|
+
this._localOplogResyncTimer = setInterval(function () {
|
|
1040
|
+
_this.queueFullResync('oplog-fallback-poll');
|
|
1041
|
+
}, this._localOplogResyncIntervalMs);
|
|
1042
|
+
}
|
|
1043
|
+
return [2 /*return*/];
|
|
1044
|
+
}
|
|
1045
|
+
});
|
|
1046
|
+
});
|
|
1047
|
+
};
|
|
1048
|
+
SubscriptionManager.prototype.getUseLocalOplog = function () {
|
|
1049
|
+
return this._useLocalOplog;
|
|
1050
|
+
};
|
|
1051
|
+
SubscriptionManager.prototype.notifyLocalOplog = function (collection, type) {
|
|
1052
|
+
var _this = this;
|
|
1053
|
+
if (type === void 0) { type = 'update'; }
|
|
1054
|
+
if (!this._useLocalOplog) {
|
|
1055
|
+
return;
|
|
1056
|
+
}
|
|
1057
|
+
setImmediate(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
1058
|
+
var _a;
|
|
1059
|
+
return __generator(this, function (_b) {
|
|
1060
|
+
switch (_b.label) {
|
|
1061
|
+
case 0:
|
|
1062
|
+
_b.trys.push([0, 2, , 3]);
|
|
1063
|
+
return [4 /*yield*/, this.invalidatePubsCache(collection, type)];
|
|
1064
|
+
case 1:
|
|
1065
|
+
_b.sent();
|
|
1066
|
+
return [3 /*break*/, 3];
|
|
1067
|
+
case 2:
|
|
1068
|
+
_a = _b.sent();
|
|
1069
|
+
return [3 /*break*/, 3];
|
|
1070
|
+
case 3: return [2 /*return*/];
|
|
1071
|
+
}
|
|
1072
|
+
});
|
|
1073
|
+
}); });
|
|
1074
|
+
};
|
|
940
1075
|
SubscriptionManager.prototype.getResumeTokenDocId = function () {
|
|
941
1076
|
if (process.env.NODE_APP_INSTANCE) {
|
|
942
1077
|
return "oplog:".concat(process.env.NODE_APP_INSTANCE);
|
|
@@ -1194,11 +1329,14 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
1194
1329
|
// Watch (tail) Mongo's operation log on the entire database (all insert/modify/delete will trigger this function)
|
|
1195
1330
|
SubscriptionManager.prototype.tailOpLog = function (resumeToken) {
|
|
1196
1331
|
return __awaiter(this, void 0, void 0, function () {
|
|
1197
|
-
var watchDatabases, pipeline, lastResumeToken_1, startedWithResumeToken, error_6;
|
|
1332
|
+
var watchDatabases, pipeline, lastResumeToken_1, startedWithResumeToken, error_6, innerError_1, error_7;
|
|
1198
1333
|
var _this = this;
|
|
1199
1334
|
return __generator(this, function (_a) {
|
|
1200
1335
|
switch (_a.label) {
|
|
1201
1336
|
case 0:
|
|
1337
|
+
if (this._useLocalOplog) {
|
|
1338
|
+
return [2 /*return*/];
|
|
1339
|
+
}
|
|
1202
1340
|
if (!(this._oplog$ && !this._oplog$.closed)) return [3 /*break*/, 2];
|
|
1203
1341
|
this._oplog$.removeAllListeners();
|
|
1204
1342
|
return [4 /*yield*/, this._oplog$.close()];
|
|
@@ -1212,7 +1350,7 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
1212
1350
|
case 3:
|
|
1213
1351
|
// eslint-disable-next-line no-restricted-syntax
|
|
1214
1352
|
_a.sent();
|
|
1215
|
-
if (!(!this._oplog$ || this._oplog$.closed)) return [3 /*break*/,
|
|
1353
|
+
if (!(!this._oplog$ || this._oplog$.closed)) return [3 /*break*/, 22];
|
|
1216
1354
|
this._oplogRetryCount += 1;
|
|
1217
1355
|
if (this._oplogRetryCount > 5) {
|
|
1218
1356
|
console.error('****************** TAIL OPLOG ERROR, RETRYING A BUNCH OF TIMES, KILLING PROCESS **************************');
|
|
@@ -1243,37 +1381,65 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
1243
1381
|
},
|
|
1244
1382
|
];
|
|
1245
1383
|
startedWithResumeToken = false;
|
|
1246
|
-
if (!resumeToken) return [3 /*break*/,
|
|
1384
|
+
if (!resumeToken) return [3 /*break*/, 17];
|
|
1247
1385
|
lastResumeToken_1 = resumeToken;
|
|
1248
1386
|
_a.label = 4;
|
|
1249
1387
|
case 4:
|
|
1250
|
-
_a.trys.push([4, 5, ,
|
|
1388
|
+
_a.trys.push([4, 5, , 16]);
|
|
1251
1389
|
this._oplog$ = resolveio_server_app_1.ResolveIOServer.getMongoConnection().watch(pipeline, { resumeAfter: resumeToken, fullDocument: 'updateLookup' });
|
|
1252
1390
|
startedWithResumeToken = true;
|
|
1253
|
-
return [3 /*break*/,
|
|
1391
|
+
return [3 /*break*/, 16];
|
|
1254
1392
|
case 5:
|
|
1255
1393
|
error_6 = _a.sent();
|
|
1256
|
-
if (!this.
|
|
1394
|
+
if (!this.isChangeStreamUnsupported(error_6)) return [3 /*break*/, 7];
|
|
1395
|
+
return [4 /*yield*/, this.enableLocalOplogFallback('change-stream-unsupported', error_6)];
|
|
1396
|
+
case 6:
|
|
1397
|
+
_a.sent();
|
|
1398
|
+
return [2 /*return*/];
|
|
1399
|
+
case 7:
|
|
1400
|
+
if (!this._oplog$) return [3 /*break*/, 9];
|
|
1257
1401
|
this._oplog$.removeAllListeners();
|
|
1258
1402
|
return [4 /*yield*/, this._oplog$.close()];
|
|
1259
|
-
case
|
|
1403
|
+
case 8:
|
|
1260
1404
|
_a.sent();
|
|
1261
1405
|
this._oplog$ = null;
|
|
1262
|
-
_a.label =
|
|
1263
|
-
case
|
|
1264
|
-
case
|
|
1406
|
+
_a.label = 9;
|
|
1407
|
+
case 9: return [4 /*yield*/, this.clearResumeToken()];
|
|
1408
|
+
case 10:
|
|
1265
1409
|
_a.sent();
|
|
1266
1410
|
lastResumeToken_1 = null;
|
|
1267
1411
|
console.log(new Date(), 'oplog resumeAfter failed, starting fresh', error_6);
|
|
1412
|
+
_a.label = 11;
|
|
1413
|
+
case 11:
|
|
1414
|
+
_a.trys.push([11, 12, , 15]);
|
|
1268
1415
|
this._oplog$ = resolveio_server_app_1.ResolveIOServer.getMongoConnection().watch(pipeline, { fullDocument: 'updateLookup' });
|
|
1269
1416
|
startedWithResumeToken = false;
|
|
1417
|
+
return [3 /*break*/, 15];
|
|
1418
|
+
case 12:
|
|
1419
|
+
innerError_1 = _a.sent();
|
|
1420
|
+
if (!this.isChangeStreamUnsupported(innerError_1)) return [3 /*break*/, 14];
|
|
1421
|
+
return [4 /*yield*/, this.enableLocalOplogFallback('change-stream-unsupported', innerError_1)];
|
|
1422
|
+
case 13:
|
|
1423
|
+
_a.sent();
|
|
1424
|
+
return [2 /*return*/];
|
|
1425
|
+
case 14: throw innerError_1;
|
|
1426
|
+
case 15:
|
|
1270
1427
|
this.queueFullResync('oplog-resumeAfter-failed');
|
|
1271
|
-
return [3 /*break*/,
|
|
1272
|
-
case
|
|
1273
|
-
case
|
|
1428
|
+
return [3 /*break*/, 16];
|
|
1429
|
+
case 16: return [3 /*break*/, 21];
|
|
1430
|
+
case 17:
|
|
1431
|
+
_a.trys.push([17, 18, , 21]);
|
|
1274
1432
|
this._oplog$ = resolveio_server_app_1.ResolveIOServer.getMongoConnection().watch(pipeline, { fullDocument: 'updateLookup' });
|
|
1275
|
-
|
|
1276
|
-
case
|
|
1433
|
+
return [3 /*break*/, 21];
|
|
1434
|
+
case 18:
|
|
1435
|
+
error_7 = _a.sent();
|
|
1436
|
+
if (!this.isChangeStreamUnsupported(error_7)) return [3 /*break*/, 20];
|
|
1437
|
+
return [4 /*yield*/, this.enableLocalOplogFallback('change-stream-unsupported', error_7)];
|
|
1438
|
+
case 19:
|
|
1439
|
+
_a.sent();
|
|
1440
|
+
return [2 /*return*/];
|
|
1441
|
+
case 20: throw error_7;
|
|
1442
|
+
case 21:
|
|
1277
1443
|
console.log(new Date(), 'oplog started', startedWithResumeToken ? '(resumeAfter)' : '');
|
|
1278
1444
|
this._oplog$.on('change', function (doc) { return __awaiter(_this, void 0, void 0, function () {
|
|
1279
1445
|
var collection, fullDocument, docId, flag, dependencyFlag;
|
|
@@ -1365,10 +1531,15 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
1365
1531
|
switch (_a.label) {
|
|
1366
1532
|
case 0:
|
|
1367
1533
|
console.log(new Date(), 'oplog error', error);
|
|
1368
|
-
return [
|
|
1534
|
+
if (!this.isChangeStreamUnsupported(error)) return [3 /*break*/, 2];
|
|
1535
|
+
return [4 /*yield*/, this.enableLocalOplogFallback('change-stream-unsupported', error)];
|
|
1369
1536
|
case 1:
|
|
1370
1537
|
_a.sent();
|
|
1371
1538
|
return [2 /*return*/];
|
|
1539
|
+
case 2: return [4 /*yield*/, this._oplog$.close()];
|
|
1540
|
+
case 3:
|
|
1541
|
+
_a.sent();
|
|
1542
|
+
return [2 /*return*/];
|
|
1372
1543
|
}
|
|
1373
1544
|
});
|
|
1374
1545
|
}); });
|
|
@@ -1399,8 +1570,8 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
1399
1570
|
}
|
|
1400
1571
|
});
|
|
1401
1572
|
}); });
|
|
1402
|
-
_a.label =
|
|
1403
|
-
case
|
|
1573
|
+
_a.label = 22;
|
|
1574
|
+
case 22: return [2 /*return*/];
|
|
1404
1575
|
}
|
|
1405
1576
|
});
|
|
1406
1577
|
});
|