@webex/plugin-meetings 3.12.0-next.6 → 3.12.0-next.60
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/AGENTS.md +9 -0
- package/dist/aiEnableRequest/index.js +15 -2
- package/dist/aiEnableRequest/index.js.map +1 -1
- package/dist/breakouts/breakout.js +8 -3
- package/dist/breakouts/breakout.js.map +1 -1
- package/dist/breakouts/index.js +26 -2
- package/dist/breakouts/index.js.map +1 -1
- package/dist/config.js +2 -0
- package/dist/config.js.map +1 -1
- package/dist/constants.js +6 -3
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/constants.js +11 -1
- package/dist/controls-options-manager/constants.js.map +1 -1
- package/dist/controls-options-manager/index.js +38 -24
- package/dist/controls-options-manager/index.js.map +1 -1
- package/dist/controls-options-manager/util.js +91 -0
- package/dist/controls-options-manager/util.js.map +1 -1
- package/dist/hashTree/constants.js +10 -1
- package/dist/hashTree/constants.js.map +1 -1
- package/dist/hashTree/hashTreeParser.js +716 -370
- package/dist/hashTree/hashTreeParser.js.map +1 -1
- package/dist/hashTree/utils.js +22 -0
- package/dist/hashTree/utils.js.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/interceptors/locusRetry.js +23 -8
- package/dist/interceptors/locusRetry.js.map +1 -1
- package/dist/interpretation/index.js +10 -1
- package/dist/interpretation/index.js.map +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/controlsUtils.js +4 -1
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +289 -87
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/types.js +19 -0
- package/dist/locus-info/types.js.map +1 -1
- package/dist/media/index.js +3 -1
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +1 -0
- package/dist/media/properties.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +3 -1
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +907 -535
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/util.js +19 -2
- package/dist/meeting/util.js.map +1 -1
- package/dist/meetings/index.js +231 -78
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/meetings.types.js +6 -1
- package/dist/meetings/meetings.types.js.map +1 -1
- package/dist/meetings/request.js +39 -0
- package/dist/meetings/request.js.map +1 -1
- package/dist/meetings/util.js +79 -5
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.js +10 -0
- package/dist/member/index.js.map +1 -1
- package/dist/member/types.js.map +1 -1
- package/dist/member/util.js +3 -0
- package/dist/member/util.js.map +1 -1
- package/dist/metrics/constants.js +4 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/multistream/codec/constants.js +63 -0
- package/dist/multistream/codec/constants.js.map +1 -0
- package/dist/multistream/mediaRequestManager.js +62 -15
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/receiveSlot.js +9 -0
- package/dist/multistream/receiveSlot.js.map +1 -1
- package/dist/reactions/reactions.type.js.map +1 -1
- package/dist/recording-controller/index.js +1 -3
- package/dist/recording-controller/index.js.map +1 -1
- package/dist/types/config.d.ts +2 -0
- package/dist/types/constants.d.ts +2 -0
- package/dist/types/controls-options-manager/constants.d.ts +6 -1
- package/dist/types/controls-options-manager/index.d.ts +10 -0
- package/dist/types/hashTree/constants.d.ts +1 -0
- package/dist/types/hashTree/hashTreeParser.d.ts +92 -16
- package/dist/types/hashTree/utils.d.ts +11 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/interceptors/locusRetry.d.ts +4 -4
- package/dist/types/locus-info/index.d.ts +46 -6
- package/dist/types/locus-info/types.d.ts +21 -1
- package/dist/types/media/properties.d.ts +1 -0
- package/dist/types/meeting/in-meeting-actions.d.ts +2 -0
- package/dist/types/meeting/index.d.ts +87 -3
- package/dist/types/meeting/util.d.ts +8 -0
- package/dist/types/meetings/index.d.ts +30 -2
- package/dist/types/meetings/meetings.types.d.ts +15 -0
- package/dist/types/meetings/request.d.ts +14 -0
- package/dist/types/member/index.d.ts +1 -0
- package/dist/types/member/types.d.ts +1 -0
- package/dist/types/member/util.d.ts +1 -0
- package/dist/types/metrics/constants.d.ts +3 -0
- package/dist/types/multistream/codec/constants.d.ts +7 -0
- package/dist/types/multistream/mediaRequestManager.d.ts +22 -5
- package/dist/types/reactions/reactions.type.d.ts +3 -0
- package/dist/webinar/index.js +361 -235
- package/dist/webinar/index.js.map +1 -1
- package/package.json +22 -22
- package/src/aiEnableRequest/index.ts +16 -0
- package/src/breakouts/breakout.ts +3 -1
- package/src/breakouts/index.ts +31 -0
- package/src/config.ts +2 -0
- package/src/constants.ts +5 -1
- package/src/controls-options-manager/constants.ts +14 -1
- package/src/controls-options-manager/index.ts +47 -24
- package/src/controls-options-manager/util.ts +81 -1
- package/src/hashTree/constants.ts +9 -0
- package/src/hashTree/hashTreeParser.ts +429 -183
- package/src/hashTree/utils.ts +17 -0
- package/src/index.ts +5 -0
- package/src/interceptors/locusRetry.ts +25 -4
- package/src/interpretation/index.ts +25 -8
- package/src/locus-info/controlsUtils.ts +3 -1
- package/src/locus-info/index.ts +291 -97
- package/src/locus-info/types.ts +25 -1
- package/src/media/index.ts +3 -0
- package/src/media/properties.ts +1 -0
- package/src/meeting/in-meeting-actions.ts +4 -0
- package/src/meeting/index.ts +388 -33
- package/src/meeting/util.ts +20 -2
- package/src/meetings/index.ts +134 -44
- package/src/meetings/meetings.types.ts +19 -0
- package/src/meetings/request.ts +43 -0
- package/src/meetings/util.ts +97 -1
- package/src/member/index.ts +10 -0
- package/src/member/types.ts +1 -0
- package/src/member/util.ts +3 -0
- package/src/metrics/constants.ts +3 -0
- package/src/multistream/codec/constants.ts +58 -0
- package/src/multistream/mediaRequestManager.ts +119 -28
- package/src/multistream/receiveSlot.ts +18 -0
- package/src/reactions/reactions.type.ts +3 -0
- package/src/recording-controller/index.ts +1 -2
- package/src/webinar/index.ts +162 -21
- package/test/unit/spec/aiEnableRequest/index.ts +86 -0
- package/test/unit/spec/breakouts/breakout.ts +9 -3
- package/test/unit/spec/breakouts/index.ts +49 -0
- package/test/unit/spec/controls-options-manager/index.js +140 -29
- package/test/unit/spec/controls-options-manager/util.js +165 -0
- package/test/unit/spec/hashTree/hashTreeParser.ts +1508 -149
- package/test/unit/spec/hashTree/utils.ts +88 -1
- package/test/unit/spec/interceptors/locusRetry.ts +205 -4
- package/test/unit/spec/interpretation/index.ts +26 -4
- package/test/unit/spec/locus-info/controlsUtils.js +172 -57
- package/test/unit/spec/locus-info/index.js +475 -81
- package/test/unit/spec/media/index.ts +31 -0
- package/test/unit/spec/meeting/in-meeting-actions.ts +2 -0
- package/test/unit/spec/meeting/index.js +1131 -49
- package/test/unit/spec/meeting/muteState.js +3 -0
- package/test/unit/spec/meeting/utils.js +33 -0
- package/test/unit/spec/meetings/index.js +360 -10
- package/test/unit/spec/meetings/request.js +141 -0
- package/test/unit/spec/meetings/utils.js +189 -0
- package/test/unit/spec/member/index.js +7 -0
- package/test/unit/spec/member/util.js +24 -0
- package/test/unit/spec/multistream/mediaRequestManager.ts +501 -37
- package/test/unit/spec/recording-controller/index.js +9 -8
- package/test/unit/spec/webinar/index.ts +141 -16
|
@@ -15,17 +15,17 @@ var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequ
|
|
|
15
15
|
_Object$defineProperty(exports, "__esModule", {
|
|
16
16
|
value: true
|
|
17
17
|
});
|
|
18
|
-
exports.default = exports.MeetingEndedError = exports.LocusInfoUpdateType = void 0;
|
|
18
|
+
exports.default = exports.MeetingEndedError = exports.LocusNotFoundError = exports.LocusInfoUpdateType = void 0;
|
|
19
19
|
var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));
|
|
20
|
-
var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
|
|
21
20
|
var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));
|
|
21
|
+
var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
|
|
22
22
|
var _isArray = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/array/is-array"));
|
|
23
23
|
var _keys = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/keys"));
|
|
24
24
|
var _values = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/values"));
|
|
25
25
|
var _parseInt2 = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/parse-int"));
|
|
26
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/toConsumableArray"));
|
|
26
27
|
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/slicedToArray"));
|
|
27
28
|
var _typeof2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/typeof"));
|
|
28
|
-
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/toConsumableArray"));
|
|
29
29
|
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/asyncToGenerator"));
|
|
30
30
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
|
|
31
31
|
var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));
|
|
@@ -37,9 +37,12 @@ var _wrapNativeSuper2 = _interopRequireDefault(require("@babel/runtime-corejs2/h
|
|
|
37
37
|
var _lodash = require("lodash");
|
|
38
38
|
var _hashTree = _interopRequireDefault(require("./hashTree"));
|
|
39
39
|
var _loggerProxy = _interopRequireDefault(require("../common/logs/logger-proxy"));
|
|
40
|
-
var
|
|
41
|
-
var
|
|
40
|
+
var _metrics = _interopRequireDefault(require("../metrics"));
|
|
41
|
+
var _constants = _interopRequireDefault(require("../metrics/constants"));
|
|
42
|
+
var _constants2 = require("../constants");
|
|
43
|
+
var _constants3 = require("./constants");
|
|
42
44
|
var _types = require("./types");
|
|
45
|
+
var _types2 = require("../locus-info/types");
|
|
43
46
|
var _utils = require("./utils");
|
|
44
47
|
function ownKeys(e, r) { var t = _Object$keys4(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
45
48
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
@@ -50,7 +53,8 @@ function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0,
|
|
|
50
53
|
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
51
54
|
var LocusInfoUpdateType = exports.LocusInfoUpdateType = {
|
|
52
55
|
OBJECTS_UPDATED: 'OBJECTS_UPDATED',
|
|
53
|
-
MEETING_ENDED: 'MEETING_ENDED'
|
|
56
|
+
MEETING_ENDED: 'MEETING_ENDED',
|
|
57
|
+
LOCUS_NOT_FOUND: 'LOCUS_NOT_FOUND'
|
|
54
58
|
};
|
|
55
59
|
/**
|
|
56
60
|
* This error is thrown if we receive information that the meeting has ended while we're processing some hash messages.
|
|
@@ -64,11 +68,24 @@ var MeetingEndedError = exports.MeetingEndedError = /*#__PURE__*/function (_Erro
|
|
|
64
68
|
(0, _inherits2.default)(MeetingEndedError, _Error);
|
|
65
69
|
return (0, _createClass2.default)(MeetingEndedError);
|
|
66
70
|
}(/*#__PURE__*/(0, _wrapNativeSuper2.default)(Error));
|
|
71
|
+
/**
|
|
72
|
+
* This error is thrown when a 404 is received from Locus hash tree endpoints, indicating that the locus URL
|
|
73
|
+
* is no longer valid (e.g. participant moved to a breakout room, or meeting ended).
|
|
74
|
+
* It's handled internally by HashTreeParser and results in LOCUS_NOT_FOUND being sent up.
|
|
75
|
+
*/
|
|
76
|
+
var LocusNotFoundError = exports.LocusNotFoundError = /*#__PURE__*/function (_Error2) {
|
|
77
|
+
function LocusNotFoundError() {
|
|
78
|
+
(0, _classCallCheck2.default)(this, LocusNotFoundError);
|
|
79
|
+
return _callSuper(this, LocusNotFoundError, arguments);
|
|
80
|
+
}
|
|
81
|
+
(0, _inherits2.default)(LocusNotFoundError, _Error2);
|
|
82
|
+
return (0, _createClass2.default)(LocusNotFoundError);
|
|
83
|
+
}(/*#__PURE__*/(0, _wrapNativeSuper2.default)(Error));
|
|
67
84
|
/* Currently Locus always sends Metadata objects only in the "self" dataset.
|
|
68
85
|
* If this ever changes, update all the code that relies on this constant.
|
|
69
86
|
*/
|
|
70
|
-
var MetadataDataSetName =
|
|
71
|
-
var PossibleSentinelMessageDataSetNames = [
|
|
87
|
+
var MetadataDataSetName = _constants3.DataSetNames.SELF;
|
|
88
|
+
var PossibleSentinelMessageDataSetNames = [_constants3.DataSetNames.MAIN, _constants3.DataSetNames.SELF, _constants3.DataSetNames.UNJOINED];
|
|
72
89
|
|
|
73
90
|
/**
|
|
74
91
|
* Parses hash tree eventing locus data
|
|
@@ -92,6 +109,10 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
92
109
|
(0, _defineProperty2.default)(this, "heartbeatIntervalMs", void 0);
|
|
93
110
|
(0, _defineProperty2.default)(this, "excludedDataSets", void 0);
|
|
94
111
|
(0, _defineProperty2.default)(this, "state", void 0);
|
|
112
|
+
(0, _defineProperty2.default)(this, "syncQueue", []);
|
|
113
|
+
(0, _defineProperty2.default)(this, "isSyncInProgress", false);
|
|
114
|
+
(0, _defineProperty2.default)(this, "isSyncAllInProgress", false);
|
|
115
|
+
(0, _defineProperty2.default)(this, "syncQueueProcessingPromise", _promise.default.resolve());
|
|
95
116
|
var _options$initialLocus = options.initialLocus,
|
|
96
117
|
dataSets = _options$initialLocus.dataSets,
|
|
97
118
|
locus = _options$initialLocus.locus; // extract dataSets from initialLocus
|
|
@@ -212,80 +233,65 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
212
233
|
*/
|
|
213
234
|
}, {
|
|
214
235
|
key: "initializeNewVisibleDataSet",
|
|
215
|
-
value: function
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
return
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
_loggerProxy.default.logger.warn("HashTreeParser#sendInitializationSyncRequestToLocus --> ".concat(this.debugId, " No data set found for ").concat(datasetName, ", cannot send the request for leaf data"));
|
|
251
|
-
return _promise.default.resolve(null);
|
|
236
|
+
value: (function () {
|
|
237
|
+
var _initializeNewVisibleDataSet = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee(visibleDataSetInfo, dataSetInfo) {
|
|
238
|
+
var hashTree;
|
|
239
|
+
return _regenerator.default.wrap(function (_context) {
|
|
240
|
+
while (1) switch (_context.prev = _context.next) {
|
|
241
|
+
case 0:
|
|
242
|
+
if (!this.isVisibleDataSet(dataSetInfo.name)) {
|
|
243
|
+
_context.next = 1;
|
|
244
|
+
break;
|
|
245
|
+
}
|
|
246
|
+
_loggerProxy.default.logger.info("HashTreeParser#initializeNewVisibleDataSet --> ".concat(this.debugId, " Data set \"").concat(dataSetInfo.name, "\" already exists, skipping init"));
|
|
247
|
+
return _context.abrupt("return");
|
|
248
|
+
case 1:
|
|
249
|
+
_loggerProxy.default.logger.info("HashTreeParser#initializeNewVisibleDataSet --> ".concat(this.debugId, " Adding visible data set \"").concat(dataSetInfo.name, "\""));
|
|
250
|
+
if (this.addToVisibleDataSetsList(visibleDataSetInfo)) {
|
|
251
|
+
_context.next = 2;
|
|
252
|
+
break;
|
|
253
|
+
}
|
|
254
|
+
return _context.abrupt("return");
|
|
255
|
+
case 2:
|
|
256
|
+
hashTree = new _hashTree.default([], dataSetInfo.leafCount);
|
|
257
|
+
this.dataSets[dataSetInfo.name] = _objectSpread(_objectSpread({}, dataSetInfo), {}, {
|
|
258
|
+
hashTree: hashTree
|
|
259
|
+
});
|
|
260
|
+
this.enqueueSyncForDataset(dataSetInfo.name, 'new visible data set initialization', true);
|
|
261
|
+
_context.next = 3;
|
|
262
|
+
return this.syncQueueProcessingPromise;
|
|
263
|
+
case 3:
|
|
264
|
+
case "end":
|
|
265
|
+
return _context.stop();
|
|
266
|
+
}
|
|
267
|
+
}, _callee, this);
|
|
268
|
+
}));
|
|
269
|
+
function initializeNewVisibleDataSet(_x, _x2) {
|
|
270
|
+
return _initializeNewVisibleDataSet.apply(this, arguments);
|
|
252
271
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
return this.sendSyncRequestToLocus(this.dataSets[datasetName], emptyLeavesData).then(function (syncResponse) {
|
|
256
|
-
if (syncResponse) {
|
|
257
|
-
return {
|
|
258
|
-
updateType: LocusInfoUpdateType.OBJECTS_UPDATED,
|
|
259
|
-
updatedObjects: _this2.parseMessage(syncResponse, "via empty leaves /sync API call for ".concat(debugText))
|
|
260
|
-
};
|
|
261
|
-
}
|
|
262
|
-
return {
|
|
263
|
-
updateType: LocusInfoUpdateType.OBJECTS_UPDATED,
|
|
264
|
-
updatedObjects: []
|
|
265
|
-
};
|
|
266
|
-
});
|
|
267
|
-
}
|
|
268
|
-
|
|
272
|
+
return initializeNewVisibleDataSet;
|
|
273
|
+
}()
|
|
269
274
|
/**
|
|
270
275
|
* Queries Locus for all up-to-date information about all visible data sets
|
|
271
276
|
*
|
|
272
277
|
* @returns {Promise}
|
|
273
278
|
*/
|
|
279
|
+
)
|
|
274
280
|
}, {
|
|
275
281
|
key: "getAllVisibleDataSetsFromLocus",
|
|
276
282
|
value: function getAllVisibleDataSetsFromLocus() {
|
|
277
|
-
var
|
|
283
|
+
var _this2 = this;
|
|
278
284
|
if (!this.visibleDataSetsUrl) {
|
|
279
285
|
_loggerProxy.default.logger.warn("HashTreeParser#getAllVisibleDataSetsFromLocus --> ".concat(this.debugId, " No visibleDataSetsUrl, cannot get data sets information"));
|
|
280
286
|
return _promise.default.resolve([]);
|
|
281
287
|
}
|
|
282
288
|
return this.webexRequest({
|
|
283
|
-
method:
|
|
289
|
+
method: _constants2.HTTP_VERBS.GET,
|
|
284
290
|
uri: this.visibleDataSetsUrl
|
|
285
291
|
}).then(function (response) {
|
|
286
292
|
return response.body.dataSets;
|
|
287
293
|
}).catch(function (error) {
|
|
288
|
-
|
|
294
|
+
_this2.checkForSentinelHttpResponse(error);
|
|
289
295
|
throw error;
|
|
290
296
|
});
|
|
291
297
|
}
|
|
@@ -299,26 +305,26 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
299
305
|
}, {
|
|
300
306
|
key: "initializeFromMessage",
|
|
301
307
|
value: (function () {
|
|
302
|
-
var _initializeFromMessage = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function
|
|
308
|
+
var _initializeFromMessage = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee2(message) {
|
|
303
309
|
var visibleDataSets;
|
|
304
|
-
return _regenerator.default.wrap(function (
|
|
305
|
-
while (1) switch (
|
|
310
|
+
return _regenerator.default.wrap(function (_context2) {
|
|
311
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
306
312
|
case 0:
|
|
307
313
|
this.visibleDataSetsUrl = message.visibleDataSetsUrl;
|
|
308
314
|
_loggerProxy.default.logger.info("HashTreeParser#initializeFromMessage --> ".concat(this.debugId, " visibleDataSetsUrl=").concat(this.visibleDataSetsUrl));
|
|
309
|
-
|
|
315
|
+
_context2.next = 1;
|
|
310
316
|
return this.getAllVisibleDataSetsFromLocus();
|
|
311
317
|
case 1:
|
|
312
|
-
visibleDataSets =
|
|
313
|
-
|
|
318
|
+
visibleDataSets = _context2.sent;
|
|
319
|
+
_context2.next = 2;
|
|
314
320
|
return this.initializeDataSets(visibleDataSets, 'initialization from message');
|
|
315
321
|
case 2:
|
|
316
322
|
case "end":
|
|
317
|
-
return
|
|
323
|
+
return _context2.stop();
|
|
318
324
|
}
|
|
319
|
-
},
|
|
325
|
+
}, _callee2, this);
|
|
320
326
|
}));
|
|
321
|
-
function initializeFromMessage(
|
|
327
|
+
function initializeFromMessage(_x3) {
|
|
322
328
|
return _initializeFromMessage.apply(this, arguments);
|
|
323
329
|
}
|
|
324
330
|
return initializeFromMessage;
|
|
@@ -336,34 +342,34 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
336
342
|
}, {
|
|
337
343
|
key: "initializeFromGetLociResponse",
|
|
338
344
|
value: (function () {
|
|
339
|
-
var _initializeFromGetLociResponse = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function
|
|
345
|
+
var _initializeFromGetLociResponse = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee3(locus) {
|
|
340
346
|
var _locus$links2, _locus$links2$resourc, _locus$links2$resourc2;
|
|
341
347
|
var visibleDataSets;
|
|
342
|
-
return _regenerator.default.wrap(function (
|
|
343
|
-
while (1) switch (
|
|
348
|
+
return _regenerator.default.wrap(function (_context3) {
|
|
349
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
344
350
|
case 0:
|
|
345
351
|
if (locus !== null && locus !== void 0 && (_locus$links2 = locus.links) !== null && _locus$links2 !== void 0 && (_locus$links2$resourc = _locus$links2.resources) !== null && _locus$links2$resourc !== void 0 && (_locus$links2$resourc2 = _locus$links2$resourc.visibleDataSets) !== null && _locus$links2$resourc2 !== void 0 && _locus$links2$resourc2.url) {
|
|
346
|
-
|
|
352
|
+
_context3.next = 1;
|
|
347
353
|
break;
|
|
348
354
|
}
|
|
349
355
|
_loggerProxy.default.logger.warn("HashTreeParser#initializeFromGetLociResponse --> ".concat(this.debugId, " missing visibleDataSets url in GET Loci response, cannot initialize hash trees"));
|
|
350
|
-
return
|
|
356
|
+
return _context3.abrupt("return");
|
|
351
357
|
case 1:
|
|
352
358
|
this.visibleDataSetsUrl = locus.links.resources.visibleDataSets.url;
|
|
353
359
|
_loggerProxy.default.logger.info("HashTreeParser#initializeFromGetLociResponse --> ".concat(this.debugId, " visibleDataSets url: ").concat(this.visibleDataSetsUrl));
|
|
354
|
-
|
|
360
|
+
_context3.next = 2;
|
|
355
361
|
return this.getAllVisibleDataSetsFromLocus();
|
|
356
362
|
case 2:
|
|
357
|
-
visibleDataSets =
|
|
358
|
-
|
|
363
|
+
visibleDataSets = _context3.sent;
|
|
364
|
+
_context3.next = 3;
|
|
359
365
|
return this.initializeDataSets(visibleDataSets, 'initialization from GET /loci response');
|
|
360
366
|
case 3:
|
|
361
367
|
case "end":
|
|
362
|
-
return
|
|
368
|
+
return _context3.stop();
|
|
363
369
|
}
|
|
364
|
-
},
|
|
370
|
+
}, _callee3, this);
|
|
365
371
|
}));
|
|
366
|
-
function initializeFromGetLociResponse(
|
|
372
|
+
function initializeFromGetLociResponse(_x4) {
|
|
367
373
|
return _initializeFromGetLociResponse.apply(this, arguments);
|
|
368
374
|
}
|
|
369
375
|
return initializeFromGetLociResponse;
|
|
@@ -379,24 +385,23 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
379
385
|
}, {
|
|
380
386
|
key: "initializeDataSets",
|
|
381
387
|
value: (function () {
|
|
382
|
-
var _initializeDataSets = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function
|
|
383
|
-
var
|
|
384
|
-
return _regenerator.default.wrap(function (
|
|
385
|
-
while (1) switch (
|
|
388
|
+
var _initializeDataSets = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee4(visibleDataSets, debugText) {
|
|
389
|
+
var _iterator2, _step2, dataSet, name, leafCount, url, _t;
|
|
390
|
+
return _regenerator.default.wrap(function (_context4) {
|
|
391
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
386
392
|
case 0:
|
|
387
393
|
if (!(this.state === 'stopped')) {
|
|
388
|
-
|
|
394
|
+
_context4.next = 1;
|
|
389
395
|
break;
|
|
390
396
|
}
|
|
391
|
-
return
|
|
397
|
+
return _context4.abrupt("return");
|
|
392
398
|
case 1:
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
_context3.prev = 2;
|
|
399
|
+
_iterator2 = _createForOfIteratorHelper((0, _utils.sortByInitPriority)(visibleDataSets, _constants3.DATA_SET_INIT_PRIORITY));
|
|
400
|
+
_context4.prev = 2;
|
|
396
401
|
_iterator2.s();
|
|
397
402
|
case 3:
|
|
398
403
|
if ((_step2 = _iterator2.n()).done) {
|
|
399
|
-
|
|
404
|
+
_context4.next = 6;
|
|
400
405
|
break;
|
|
401
406
|
}
|
|
402
407
|
dataSet = _step2.value;
|
|
@@ -408,59 +413,47 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
408
413
|
_loggerProxy.default.logger.info("HashTreeParser#initializeDataSets --> ".concat(this.debugId, " dataset \"").concat(name, "\" already exists (").concat(debugText, ")"));
|
|
409
414
|
}
|
|
410
415
|
if (this.isVisibleDataSet(name)) {
|
|
411
|
-
|
|
416
|
+
_context4.next = 4;
|
|
412
417
|
break;
|
|
413
418
|
}
|
|
414
419
|
if (this.addToVisibleDataSetsList({
|
|
415
420
|
name: name,
|
|
416
421
|
url: url
|
|
417
422
|
})) {
|
|
418
|
-
|
|
423
|
+
_context4.next = 4;
|
|
419
424
|
break;
|
|
420
425
|
}
|
|
421
|
-
return
|
|
426
|
+
return _context4.abrupt("continue", 5);
|
|
422
427
|
case 4:
|
|
423
|
-
if (this.dataSets[name].hashTree) {
|
|
424
|
-
|
|
425
|
-
|
|
428
|
+
if (!this.dataSets[name].hashTree) {
|
|
429
|
+
_loggerProxy.default.logger.info("HashTreeParser#initializeDataSets --> ".concat(this.debugId, " creating hash tree for visible dataset \"").concat(name, "\" (").concat(debugText, ")"));
|
|
430
|
+
this.dataSets[name].hashTree = new _hashTree.default([], leafCount);
|
|
431
|
+
this.enqueueSyncForDataset(name, "initialization sync for ".concat(debugText), true);
|
|
426
432
|
}
|
|
427
|
-
_loggerProxy.default.logger.info("HashTreeParser#initializeDataSets --> ".concat(this.debugId, " creating hash tree for visible dataset \"").concat(name, "\" (").concat(debugText, ")"));
|
|
428
|
-
this.dataSets[name].hashTree = new _hashTree.default([], leafCount);
|
|
429
|
-
|
|
430
|
-
// eslint-disable-next-line no-await-in-loop
|
|
431
|
-
_context3.next = 5;
|
|
432
|
-
return this.sendInitializationSyncRequestToLocus(name, debugText);
|
|
433
433
|
case 5:
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
updatedObjects.push.apply(updatedObjects, (0, _toConsumableArray2.default)(_data.updatedObjects || []));
|
|
437
|
-
}
|
|
434
|
+
_context4.next = 3;
|
|
435
|
+
break;
|
|
438
436
|
case 6:
|
|
439
|
-
|
|
437
|
+
_context4.next = 8;
|
|
440
438
|
break;
|
|
441
439
|
case 7:
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
case 8:
|
|
445
|
-
_context3.prev = 8;
|
|
446
|
-
_t = _context3["catch"](2);
|
|
440
|
+
_context4.prev = 7;
|
|
441
|
+
_t = _context4["catch"](2);
|
|
447
442
|
_iterator2.e(_t);
|
|
448
|
-
case
|
|
449
|
-
|
|
443
|
+
case 8:
|
|
444
|
+
_context4.prev = 8;
|
|
450
445
|
_iterator2.f();
|
|
451
|
-
return
|
|
446
|
+
return _context4.finish(8);
|
|
447
|
+
case 9:
|
|
448
|
+
_context4.next = 10;
|
|
449
|
+
return this.syncQueueProcessingPromise;
|
|
452
450
|
case 10:
|
|
453
|
-
this.callLocusInfoUpdateCallback({
|
|
454
|
-
updateType: LocusInfoUpdateType.OBJECTS_UPDATED,
|
|
455
|
-
updatedObjects: updatedObjects
|
|
456
|
-
});
|
|
457
|
-
case 11:
|
|
458
451
|
case "end":
|
|
459
|
-
return
|
|
452
|
+
return _context4.stop();
|
|
460
453
|
}
|
|
461
|
-
},
|
|
454
|
+
}, _callee4, this, [[2, 7, 8, 9]]);
|
|
462
455
|
}));
|
|
463
|
-
function initializeDataSets(
|
|
456
|
+
function initializeDataSets(_x5, _x6) {
|
|
464
457
|
return _initializeDataSets.apply(this, arguments);
|
|
465
458
|
}
|
|
466
459
|
return initializeDataSets;
|
|
@@ -596,9 +589,9 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
596
589
|
}, {
|
|
597
590
|
key: "isEndMessage",
|
|
598
591
|
value: function isEndMessage(message) {
|
|
599
|
-
var
|
|
592
|
+
var _this3 = this;
|
|
600
593
|
return message.dataSets.some(function (dataSet) {
|
|
601
|
-
if (dataSet.leafCount === 1 && dataSet.root ===
|
|
594
|
+
if (dataSet.leafCount === 1 && dataSet.root === _constants3.EMPTY_HASH && (!_this3.dataSets[dataSet.name] || _this3.dataSets[dataSet.name].version < dataSet.version) && PossibleSentinelMessageDataSetNames.includes(dataSet.name.toLowerCase())) {
|
|
602
595
|
// this is a special way for Locus to indicate that this meeting has ended
|
|
603
596
|
return true;
|
|
604
597
|
}
|
|
@@ -615,7 +608,7 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
615
608
|
}, {
|
|
616
609
|
key: "handleRootHashHeartBeatMessage",
|
|
617
610
|
value: function handleRootHashHeartBeatMessage(message) {
|
|
618
|
-
var
|
|
611
|
+
var _this4 = this;
|
|
619
612
|
var dataSets = message.dataSets;
|
|
620
613
|
_loggerProxy.default.logger.info("HashTreeParser#handleRootHashMessage --> ".concat(this.debugId, " Received heartbeat root hash message with data sets: ").concat((0, _stringify.default)(dataSets.map(function (_ref2) {
|
|
621
614
|
var name = _ref2.name,
|
|
@@ -629,12 +622,40 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
629
622
|
version: version
|
|
630
623
|
};
|
|
631
624
|
}))));
|
|
625
|
+
this.cancelPendingSyncsForDataSets(dataSets.map(function (ds) {
|
|
626
|
+
return ds.name;
|
|
627
|
+
}));
|
|
632
628
|
dataSets.forEach(function (dataSet) {
|
|
633
|
-
|
|
634
|
-
|
|
629
|
+
_this4.updateDataSetInfo(dataSet);
|
|
630
|
+
_this4.runSyncAlgorithm(dataSet);
|
|
635
631
|
});
|
|
636
632
|
}
|
|
637
633
|
|
|
634
|
+
/**
|
|
635
|
+
* Handles known errors that can happen during syncs
|
|
636
|
+
*
|
|
637
|
+
* @param {any} error - The error to handle
|
|
638
|
+
* @returns {boolean} true if the error was recognized and handled, false otherwise
|
|
639
|
+
*/
|
|
640
|
+
}, {
|
|
641
|
+
key: "handleSyncErrors",
|
|
642
|
+
value: function handleSyncErrors(error) {
|
|
643
|
+
if (error instanceof MeetingEndedError) {
|
|
644
|
+
this.callLocusInfoUpdateCallback({
|
|
645
|
+
updateType: LocusInfoUpdateType.MEETING_ENDED
|
|
646
|
+
});
|
|
647
|
+
return true;
|
|
648
|
+
}
|
|
649
|
+
if (error instanceof LocusNotFoundError) {
|
|
650
|
+
this.callLocusInfoUpdateCallback({
|
|
651
|
+
updateType: LocusInfoUpdateType.LOCUS_NOT_FOUND
|
|
652
|
+
});
|
|
653
|
+
this.stop();
|
|
654
|
+
return true;
|
|
655
|
+
}
|
|
656
|
+
return false;
|
|
657
|
+
}
|
|
658
|
+
|
|
638
659
|
/**
|
|
639
660
|
* Asynchronously initializes new visible data sets
|
|
640
661
|
*
|
|
@@ -644,18 +665,14 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
644
665
|
}, {
|
|
645
666
|
key: "queueInitForNewVisibleDataSets",
|
|
646
667
|
value: function queueInitForNewVisibleDataSets(dataSetsRequiringInitialization) {
|
|
647
|
-
var
|
|
668
|
+
var _this5 = this;
|
|
648
669
|
_loggerProxy.default.logger.info("HashTreeParser#queueInitForNewVisibleDataSets --> ".concat(this.debugId, " queuing initialization of new visible datasets: ").concat(dataSetsRequiringInitialization.map(function (ds) {
|
|
649
670
|
return ds.name;
|
|
650
671
|
}).join(', ')));
|
|
651
672
|
queueMicrotask(function () {
|
|
652
|
-
|
|
653
|
-
if (error
|
|
654
|
-
|
|
655
|
-
updateType: LocusInfoUpdateType.MEETING_ENDED
|
|
656
|
-
});
|
|
657
|
-
} else {
|
|
658
|
-
_loggerProxy.default.logger.warn("HashTreeParser#queueInitForNewVisibleDataSets --> ".concat(_this6.debugId, " error while initializing new visible datasets: ").concat(dataSetsRequiringInitialization.map(function (ds) {
|
|
673
|
+
_this5.initializeNewVisibleDataSets(dataSetsRequiringInitialization).catch(function (error) {
|
|
674
|
+
if (!_this5.handleSyncErrors(error)) {
|
|
675
|
+
_loggerProxy.default.logger.warn("HashTreeParser#queueInitForNewVisibleDataSets --> ".concat(_this5.debugId, " error while initializing new visible datasets: ").concat(dataSetsRequiringInitialization.map(function (ds) {
|
|
659
676
|
return ds.name;
|
|
660
677
|
}).join(', '), ": "), error);
|
|
661
678
|
}
|
|
@@ -715,14 +732,18 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
715
732
|
}, {
|
|
716
733
|
key: "handleLocusUpdate",
|
|
717
734
|
value: function handleLocusUpdate(update) {
|
|
718
|
-
var
|
|
735
|
+
var _this6 = this;
|
|
719
736
|
if (this.state === 'stopped') {
|
|
720
737
|
return;
|
|
721
738
|
}
|
|
722
739
|
var dataSets = update.dataSets,
|
|
723
740
|
locus = update.locus,
|
|
724
741
|
metadata = update.metadata;
|
|
742
|
+
_loggerProxy.default.logger.info("HashTreeParser#handleLocusUpdate --> ".concat(this.debugId, " received update with dataSets=").concat(dataSets === null || dataSets === void 0 ? void 0 : dataSets.map(function (ds) {
|
|
743
|
+
return ds.name;
|
|
744
|
+
}).join(','), " metadata=").concat(metadata ? 'yes' : 'no'));
|
|
725
745
|
if (!dataSets) {
|
|
746
|
+
// this happens for example when we handle GET /loci response
|
|
726
747
|
_loggerProxy.default.logger.info("HashTreeParser#handleLocusUpdate --> ".concat(this.debugId, " received hash tree update without dataSets"));
|
|
727
748
|
} else {
|
|
728
749
|
var _iterator5 = _createForOfIteratorHelper(dataSets),
|
|
@@ -752,9 +773,9 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
752
773
|
|
|
753
774
|
// then process the data in hash trees, if it is a new version, then add it to updatedObjects
|
|
754
775
|
(0, _keys.default)(leafInfo).forEach(function (dataSetName) {
|
|
755
|
-
if (
|
|
756
|
-
if (
|
|
757
|
-
var appliedChangesList =
|
|
776
|
+
if (_this6.dataSets[dataSetName]) {
|
|
777
|
+
if (_this6.dataSets[dataSetName].hashTree) {
|
|
778
|
+
var appliedChangesList = _this6.dataSets[dataSetName].hashTree.putItems(leafInfo[dataSetName].map(function (leaf) {
|
|
758
779
|
return {
|
|
759
780
|
id: leaf.id,
|
|
760
781
|
type: leaf.type,
|
|
@@ -781,10 +802,10 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
781
802
|
});
|
|
782
803
|
} else {
|
|
783
804
|
// no hash tree means that the data set is not visible
|
|
784
|
-
_loggerProxy.default.logger.warn("HashTreeParser#handleLocusUpdate --> ".concat(
|
|
805
|
+
_loggerProxy.default.logger.warn("HashTreeParser#handleLocusUpdate --> ".concat(_this6.debugId, " received leaf data for data set \"").concat(dataSetName, "\" that has no hash tree created, ignoring"));
|
|
785
806
|
}
|
|
786
807
|
} else {
|
|
787
|
-
_loggerProxy.default.logger.info("HashTreeParser#handleLocusUpdate --> ".concat(
|
|
808
|
+
_loggerProxy.default.logger.info("HashTreeParser#handleLocusUpdate --> ".concat(_this6.debugId, " received leaf data for unknown data set \"").concat(dataSetName, "\", ignoring"));
|
|
788
809
|
}
|
|
789
810
|
});
|
|
790
811
|
if (updatedObjects.length === 0) {
|
|
@@ -824,6 +845,21 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
824
845
|
}
|
|
825
846
|
}
|
|
826
847
|
|
|
848
|
+
/**
|
|
849
|
+
* Updates the leaf count for a data set, resizing its hash tree accordingly.
|
|
850
|
+
*
|
|
851
|
+
* @param {InternalDataSet} dataSet - The data set to update
|
|
852
|
+
* @param {number} newLeafCount - The new leaf count
|
|
853
|
+
* @returns {void}
|
|
854
|
+
*/
|
|
855
|
+
}, {
|
|
856
|
+
key: "updateDataSetLeafCount",
|
|
857
|
+
value: function updateDataSetLeafCount(dataSet, newLeafCount) {
|
|
858
|
+
var _dataSet$hashTree;
|
|
859
|
+
(_dataSet$hashTree = dataSet.hashTree) === null || _dataSet$hashTree === void 0 ? void 0 : _dataSet$hashTree.resize(newLeafCount);
|
|
860
|
+
dataSet.leafCount = newLeafCount;
|
|
861
|
+
}
|
|
862
|
+
|
|
827
863
|
/**
|
|
828
864
|
* Checks for changes in the visible data sets based on the updated objects.
|
|
829
865
|
* @param {HashTreeObject[]} updatedObjects - The list of updated hash tree objects.
|
|
@@ -832,7 +868,7 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
832
868
|
}, {
|
|
833
869
|
key: "checkForVisibleDataSetChanges",
|
|
834
870
|
value: function checkForVisibleDataSetChanges(updatedObjects) {
|
|
835
|
-
var
|
|
871
|
+
var _this7 = this;
|
|
836
872
|
var removedDataSets = [];
|
|
837
873
|
var addedDataSets = [];
|
|
838
874
|
|
|
@@ -841,20 +877,20 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
841
877
|
var _object$data;
|
|
842
878
|
if ((0, _utils.isMetadata)(object) && (_object$data = object.data) !== null && _object$data !== void 0 && _object$data.visibleDataSets) {
|
|
843
879
|
var newVisibleDataSets = object.data.visibleDataSets.filter(function (vds) {
|
|
844
|
-
return !
|
|
880
|
+
return !_this7.isExcludedDataSet(vds.name);
|
|
845
881
|
});
|
|
846
|
-
removedDataSets =
|
|
882
|
+
removedDataSets = _this7.visibleDataSets.filter(function (ds) {
|
|
847
883
|
return !newVisibleDataSets.some(function (nvs) {
|
|
848
884
|
return nvs.name === ds.name;
|
|
849
885
|
});
|
|
850
886
|
});
|
|
851
887
|
addedDataSets = newVisibleDataSets.filter(function (nvs) {
|
|
852
|
-
return
|
|
888
|
+
return _this7.visibleDataSets.every(function (ds) {
|
|
853
889
|
return ds.name !== nvs.name;
|
|
854
890
|
});
|
|
855
891
|
});
|
|
856
892
|
if (removedDataSets.length > 0 || addedDataSets.length > 0) {
|
|
857
|
-
_loggerProxy.default.logger.info("HashTreeParser#checkForVisibleDataSetChanges --> ".concat(
|
|
893
|
+
_loggerProxy.default.logger.info("HashTreeParser#checkForVisibleDataSetChanges --> ".concat(_this7.debugId, " visible data sets change: removed: ").concat(removedDataSets.map(function (ds) {
|
|
858
894
|
return ds.name;
|
|
859
895
|
}).join(', '), ", added: ").concat(addedDataSets.map(function (ds) {
|
|
860
896
|
return ds.name;
|
|
@@ -878,7 +914,10 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
878
914
|
}, {
|
|
879
915
|
key: "deleteHashTree",
|
|
880
916
|
value: function deleteHashTree(dataSetName) {
|
|
917
|
+
var _this$dataSets$dataSe;
|
|
881
918
|
this.dataSets[dataSetName].hashTree = undefined;
|
|
919
|
+
(_this$dataSets$dataSe = this.dataSets[dataSetName].syncAbortController) === null || _this$dataSets$dataSe === void 0 ? void 0 : _this$dataSets$dataSe.abort();
|
|
920
|
+
this.dataSets[dataSetName].syncAbortController = undefined;
|
|
882
921
|
|
|
883
922
|
// we also need to stop the timers as there is no hash tree anymore to sync
|
|
884
923
|
if (this.dataSets[dataSetName].timer) {
|
|
@@ -908,16 +947,16 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
908
947
|
}, {
|
|
909
948
|
key: "processVisibleDataSetChanges",
|
|
910
949
|
value: function processVisibleDataSetChanges(removedDataSets, addedDataSets, updatedObjects) {
|
|
911
|
-
var
|
|
950
|
+
var _this8 = this;
|
|
912
951
|
var dataSetsRequiringInitialization = [];
|
|
913
952
|
|
|
914
953
|
// if a visible data set was removed, we need to tell our client that all objects from it are removed
|
|
915
954
|
var removedObjects = [];
|
|
916
955
|
removedDataSets.forEach(function (ds) {
|
|
917
|
-
var
|
|
918
|
-
if ((
|
|
919
|
-
for (var i = 0; i <
|
|
920
|
-
removedObjects.push.apply(removedObjects, (0, _toConsumableArray2.default)(
|
|
956
|
+
var _this8$dataSets$ds$na;
|
|
957
|
+
if ((_this8$dataSets$ds$na = _this8.dataSets[ds.name]) !== null && _this8$dataSets$ds$na !== void 0 && _this8$dataSets$ds$na.hashTree) {
|
|
958
|
+
for (var i = 0; i < _this8.dataSets[ds.name].hashTree.numLeaves; i += 1) {
|
|
959
|
+
removedObjects.push.apply(removedObjects, (0, _toConsumableArray2.default)(_this8.dataSets[ds.name].hashTree.getLeafData(i).map(function (elementId) {
|
|
921
960
|
return {
|
|
922
961
|
htMeta: {
|
|
923
962
|
elementId: elementId,
|
|
@@ -927,7 +966,7 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
927
966
|
};
|
|
928
967
|
})));
|
|
929
968
|
}
|
|
930
|
-
|
|
969
|
+
_this8.deleteHashTree(ds.name);
|
|
931
970
|
}
|
|
932
971
|
});
|
|
933
972
|
this.visibleDataSets = this.visibleDataSets.filter(function (vds) {
|
|
@@ -988,81 +1027,78 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
988
1027
|
}, {
|
|
989
1028
|
key: "initializeNewVisibleDataSets",
|
|
990
1029
|
value: (function () {
|
|
991
|
-
var _initializeNewVisibleDataSets = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function
|
|
992
|
-
var
|
|
1030
|
+
var _initializeNewVisibleDataSets = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee5(addedDataSets) {
|
|
1031
|
+
var _this9 = this;
|
|
993
1032
|
var allDataSets, _iterator7, _step7, _loop, _t2;
|
|
994
|
-
return _regenerator.default.wrap(function (
|
|
995
|
-
while (1) switch (
|
|
1033
|
+
return _regenerator.default.wrap(function (_context6) {
|
|
1034
|
+
while (1) switch (_context6.prev = _context6.next) {
|
|
996
1035
|
case 0:
|
|
997
1036
|
if (!(this.state === 'stopped')) {
|
|
998
|
-
|
|
1037
|
+
_context6.next = 1;
|
|
999
1038
|
break;
|
|
1000
1039
|
}
|
|
1001
|
-
return
|
|
1040
|
+
return _context6.abrupt("return");
|
|
1002
1041
|
case 1:
|
|
1003
|
-
|
|
1042
|
+
_context6.next = 2;
|
|
1004
1043
|
return this.getAllVisibleDataSetsFromLocus();
|
|
1005
1044
|
case 2:
|
|
1006
|
-
allDataSets =
|
|
1007
|
-
_iterator7 = _createForOfIteratorHelper(addedDataSets);
|
|
1008
|
-
|
|
1045
|
+
allDataSets = _context6.sent;
|
|
1046
|
+
_iterator7 = _createForOfIteratorHelper((0, _utils.sortByInitPriority)(addedDataSets, _constants3.DATA_SET_INIT_PRIORITY));
|
|
1047
|
+
_context6.prev = 3;
|
|
1009
1048
|
_loop = /*#__PURE__*/_regenerator.default.mark(function _loop() {
|
|
1010
|
-
var ds, dataSetInfo
|
|
1011
|
-
return _regenerator.default.wrap(function (
|
|
1012
|
-
while (1) switch (
|
|
1049
|
+
var ds, dataSetInfo;
|
|
1050
|
+
return _regenerator.default.wrap(function (_context5) {
|
|
1051
|
+
while (1) switch (_context5.prev = _context5.next) {
|
|
1013
1052
|
case 0:
|
|
1014
1053
|
ds = _step7.value;
|
|
1015
1054
|
dataSetInfo = allDataSets.find(function (d) {
|
|
1016
1055
|
return d.name === ds.name;
|
|
1017
1056
|
});
|
|
1018
|
-
_loggerProxy.default.logger.info("HashTreeParser#initializeNewVisibleDataSets --> ".concat(
|
|
1057
|
+
_loggerProxy.default.logger.info("HashTreeParser#initializeNewVisibleDataSets --> ".concat(_this9.debugId, " initializing data set \"").concat(ds.name, "\""));
|
|
1019
1058
|
if (dataSetInfo) {
|
|
1020
|
-
|
|
1059
|
+
_context5.next = 1;
|
|
1021
1060
|
break;
|
|
1022
1061
|
}
|
|
1023
|
-
_loggerProxy.default.logger.warn("HashTreeParser#initializeNewVisibleDataSets --> ".concat(
|
|
1024
|
-
|
|
1062
|
+
_loggerProxy.default.logger.warn("HashTreeParser#initializeNewVisibleDataSets --> ".concat(_this9.debugId, " missing info about data set \"").concat(ds.name, "\" in Locus response from visibleDataSetsUrl"));
|
|
1063
|
+
_context5.next = 2;
|
|
1025
1064
|
break;
|
|
1026
1065
|
case 1:
|
|
1027
|
-
|
|
1028
|
-
return
|
|
1066
|
+
_context5.next = 2;
|
|
1067
|
+
return _this9.initializeNewVisibleDataSet(ds, dataSetInfo);
|
|
1029
1068
|
case 2:
|
|
1030
|
-
updates = _context4.sent;
|
|
1031
|
-
_this0.callLocusInfoUpdateCallback(updates);
|
|
1032
|
-
case 3:
|
|
1033
1069
|
case "end":
|
|
1034
|
-
return
|
|
1070
|
+
return _context5.stop();
|
|
1035
1071
|
}
|
|
1036
1072
|
}, _loop);
|
|
1037
1073
|
});
|
|
1038
1074
|
_iterator7.s();
|
|
1039
1075
|
case 4:
|
|
1040
1076
|
if ((_step7 = _iterator7.n()).done) {
|
|
1041
|
-
|
|
1077
|
+
_context6.next = 6;
|
|
1042
1078
|
break;
|
|
1043
1079
|
}
|
|
1044
|
-
return
|
|
1080
|
+
return _context6.delegateYield(_loop(), "t0", 5);
|
|
1045
1081
|
case 5:
|
|
1046
|
-
|
|
1082
|
+
_context6.next = 4;
|
|
1047
1083
|
break;
|
|
1048
1084
|
case 6:
|
|
1049
|
-
|
|
1085
|
+
_context6.next = 8;
|
|
1050
1086
|
break;
|
|
1051
1087
|
case 7:
|
|
1052
|
-
|
|
1053
|
-
_t2 =
|
|
1088
|
+
_context6.prev = 7;
|
|
1089
|
+
_t2 = _context6["catch"](3);
|
|
1054
1090
|
_iterator7.e(_t2);
|
|
1055
1091
|
case 8:
|
|
1056
|
-
|
|
1092
|
+
_context6.prev = 8;
|
|
1057
1093
|
_iterator7.f();
|
|
1058
|
-
return
|
|
1094
|
+
return _context6.finish(8);
|
|
1059
1095
|
case 9:
|
|
1060
1096
|
case "end":
|
|
1061
|
-
return
|
|
1097
|
+
return _context6.stop();
|
|
1062
1098
|
}
|
|
1063
|
-
},
|
|
1099
|
+
}, _callee5, this, [[3, 7, 8, 9]]);
|
|
1064
1100
|
}));
|
|
1065
|
-
function initializeNewVisibleDataSets(
|
|
1101
|
+
function initializeNewVisibleDataSets(_x7) {
|
|
1066
1102
|
return _initializeNewVisibleDataSets.apply(this, arguments);
|
|
1067
1103
|
}
|
|
1068
1104
|
return initializeNewVisibleDataSets;
|
|
@@ -1078,25 +1114,37 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1078
1114
|
}, {
|
|
1079
1115
|
key: "parseMessage",
|
|
1080
1116
|
value: function parseMessage(message, debugText) {
|
|
1081
|
-
var _message$
|
|
1082
|
-
|
|
1083
|
-
_message$locusStateEl2
|
|
1117
|
+
var _message$dataSets,
|
|
1118
|
+
_message$locusStateEl,
|
|
1119
|
+
_message$locusStateEl2,
|
|
1120
|
+
_this0 = this;
|
|
1084
1121
|
if (this.state === 'stopped') {
|
|
1085
1122
|
return [];
|
|
1086
1123
|
}
|
|
1087
1124
|
var dataSets = message.dataSets,
|
|
1088
1125
|
visibleDataSetsUrl = message.visibleDataSetsUrl;
|
|
1089
|
-
_loggerProxy.default.logger.info("HashTreeParser#parseMessage --> ".concat(this.debugId, "
|
|
1090
|
-
|
|
1126
|
+
_loggerProxy.default.logger.info("HashTreeParser#parseMessage --> ".concat(this.debugId, " ").concat(debugText || '', " dataSets: ").concat((_message$dataSets = message.dataSets) === null || _message$dataSets === void 0 ? void 0 : _message$dataSets.map(function (_ref5) {
|
|
1127
|
+
var name = _ref5.name,
|
|
1128
|
+
version = _ref5.version;
|
|
1129
|
+
return "".concat(name, ":").concat(version);
|
|
1130
|
+
}).join(','), ", elements: ").concat((_message$locusStateEl = message.locusStateElements) === null || _message$locusStateEl === void 0 ? void 0 : _message$locusStateEl.map(function (el) {
|
|
1131
|
+
return "".concat(el.htMeta.elementId.type, ":").concat(el.htMeta.elementId.id, ":").concat(el.htMeta.elementId.version).concat(el.data ? '+' : '-');
|
|
1132
|
+
}).join(',')));
|
|
1133
|
+
if (((_message$locusStateEl2 = message.locusStateElements) === null || _message$locusStateEl2 === void 0 ? void 0 : _message$locusStateEl2.length) === 0) {
|
|
1091
1134
|
_loggerProxy.default.logger.warn("HashTreeParser#parseMessage --> ".concat(this.debugId, " got empty locusStateElements!!!"));
|
|
1092
|
-
|
|
1135
|
+
_metrics.default.sendBehavioralMetric(_constants.default.HASH_TREE_EMPTY_LOCUS_STATE_ELEMENTS, {
|
|
1136
|
+
debugId: this.debugId
|
|
1137
|
+
});
|
|
1093
1138
|
}
|
|
1094
1139
|
|
|
1095
1140
|
// first, update our metadata about the datasets with info from the message
|
|
1096
1141
|
this.visibleDataSetsUrl = visibleDataSetsUrl;
|
|
1097
1142
|
dataSets.forEach(function (dataSet) {
|
|
1098
|
-
return
|
|
1143
|
+
return _this0.updateDataSetInfo(dataSet);
|
|
1099
1144
|
});
|
|
1145
|
+
this.cancelPendingSyncsForDataSets(dataSets.map(function (ds) {
|
|
1146
|
+
return ds.name;
|
|
1147
|
+
}));
|
|
1100
1148
|
var updatedObjects = [];
|
|
1101
1149
|
|
|
1102
1150
|
// when we detect new visible datasets, it may be that the metadata about them is not
|
|
@@ -1115,9 +1163,9 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1115
1163
|
_step8;
|
|
1116
1164
|
try {
|
|
1117
1165
|
for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
|
|
1118
|
-
var
|
|
1166
|
+
var _this0$dataSets$dataS;
|
|
1119
1167
|
var dataSetName = _step8.value;
|
|
1120
|
-
var hashTree = (
|
|
1168
|
+
var hashTree = (_this0$dataSets$dataS = _this0.dataSets[dataSetName]) === null || _this0$dataSets$dataS === void 0 ? void 0 : _this0$dataSets$dataS.hashTree;
|
|
1121
1169
|
if (hashTree && object.data) {
|
|
1122
1170
|
if (hashTree.putItem(object.htMeta.elementId)) {
|
|
1123
1171
|
updatedMetadataObjects.push(object);
|
|
@@ -1139,13 +1187,13 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1139
1187
|
dataSetsRequiringInitialization = this.processVisibleDataSetChanges(removedDataSets, addedDataSets, updatedObjects);
|
|
1140
1188
|
}
|
|
1141
1189
|
}
|
|
1142
|
-
if (
|
|
1190
|
+
if (message.locusStateElements && message.locusStateElements.length > 0) {
|
|
1143
1191
|
// by this point we now have this.dataSets setup for data sets from this message
|
|
1144
1192
|
// and hash trees created for the new visible data sets,
|
|
1145
1193
|
// so we can now process all the updates from the message
|
|
1146
1194
|
dataSets.forEach(function (dataSet) {
|
|
1147
|
-
if (
|
|
1148
|
-
var hashTree =
|
|
1195
|
+
if (_this0.dataSets[dataSet.name]) {
|
|
1196
|
+
var hashTree = _this0.dataSets[dataSet.name].hashTree;
|
|
1149
1197
|
if (hashTree) {
|
|
1150
1198
|
var locusStateElementsForThisSet = message.locusStateElements.filter(function (object) {
|
|
1151
1199
|
return object.htMeta.dataSetNames.includes(dataSet.name);
|
|
@@ -1159,20 +1207,20 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1159
1207
|
item: object.htMeta.elementId
|
|
1160
1208
|
};
|
|
1161
1209
|
}));
|
|
1162
|
-
(0, _lodash.zip)(appliedChangesList, locusStateElementsForThisSet).forEach(function (
|
|
1163
|
-
var
|
|
1164
|
-
changeApplied =
|
|
1165
|
-
object =
|
|
1210
|
+
(0, _lodash.zip)(appliedChangesList, locusStateElementsForThisSet).forEach(function (_ref6) {
|
|
1211
|
+
var _ref7 = (0, _slicedToArray2.default)(_ref6, 2),
|
|
1212
|
+
changeApplied = _ref7[0],
|
|
1213
|
+
object = _ref7[1];
|
|
1166
1214
|
if (changeApplied) {
|
|
1167
1215
|
// add to updatedObjects so that our locus DTO will get updated with the new object
|
|
1168
1216
|
updatedObjects.push(object);
|
|
1169
1217
|
}
|
|
1170
1218
|
});
|
|
1171
1219
|
} else {
|
|
1172
|
-
_loggerProxy.default.logger.info("Locus-info:index#parseMessage --> ".concat(
|
|
1220
|
+
_loggerProxy.default.logger.info("Locus-info:index#parseMessage --> ".concat(_this0.debugId, " unexpected (not visible) dataSet ").concat(dataSet.name, " received in hash tree message"));
|
|
1173
1221
|
}
|
|
1174
1222
|
}
|
|
1175
|
-
|
|
1223
|
+
_this0.runSyncAlgorithm(dataSet);
|
|
1176
1224
|
});
|
|
1177
1225
|
}
|
|
1178
1226
|
if (dataSetsRequiringInitialization.length > 0) {
|
|
@@ -1229,25 +1277,25 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1229
1277
|
}, {
|
|
1230
1278
|
key: "callLocusInfoUpdateCallback",
|
|
1231
1279
|
value: function callLocusInfoUpdateCallback(updates) {
|
|
1232
|
-
var
|
|
1280
|
+
var _updates$updatedObjec,
|
|
1281
|
+
_this1 = this;
|
|
1233
1282
|
if (this.state === 'stopped') {
|
|
1234
1283
|
return;
|
|
1235
1284
|
}
|
|
1236
|
-
var updateType = updates.updateType
|
|
1237
|
-
|
|
1238
|
-
if (updateType === LocusInfoUpdateType.OBJECTS_UPDATED && (updatedObjects === null || updatedObjects === void 0 ? void 0 : updatedObjects.length) > 0) {
|
|
1285
|
+
var updateType = updates.updateType;
|
|
1286
|
+
if (updateType === LocusInfoUpdateType.OBJECTS_UPDATED && ((_updates$updatedObjec = updates.updatedObjects) === null || _updates$updatedObjec === void 0 ? void 0 : _updates$updatedObjec.length) > 0) {
|
|
1239
1287
|
// Filter out updates for objects that already have a higher version in their datasets,
|
|
1240
1288
|
// or removals for objects that still exist in any of their datasets
|
|
1241
|
-
var filteredUpdates = updatedObjects.filter(function (object) {
|
|
1289
|
+
var filteredUpdates = updates.updatedObjects.filter(function (object) {
|
|
1242
1290
|
var elementId = object.htMeta.elementId;
|
|
1243
1291
|
var type = elementId.type,
|
|
1244
1292
|
id = elementId.id,
|
|
1245
1293
|
version = elementId.version;
|
|
1246
1294
|
|
|
1247
1295
|
// Check all datasets
|
|
1248
|
-
for (var _i2 = 0, _Object$keys3 = (0, _keys.default)(
|
|
1296
|
+
for (var _i2 = 0, _Object$keys3 = (0, _keys.default)(_this1.dataSets); _i2 < _Object$keys3.length; _i2++) {
|
|
1249
1297
|
var dataSetName = _Object$keys3[_i2];
|
|
1250
|
-
var dataSet =
|
|
1298
|
+
var dataSet = _this1.dataSets[dataSetName];
|
|
1251
1299
|
|
|
1252
1300
|
// only visible datasets have hash trees set
|
|
1253
1301
|
if (dataSet !== null && dataSet !== void 0 && dataSet.hashTree) {
|
|
@@ -1256,12 +1304,12 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1256
1304
|
if (object.data) {
|
|
1257
1305
|
// For updates: filter out if any dataset has a higher version
|
|
1258
1306
|
if (existingVersion > version) {
|
|
1259
|
-
_loggerProxy.default.logger.info("HashTreeParser#callLocusInfoUpdateCallback --> ".concat(
|
|
1307
|
+
_loggerProxy.default.logger.info("HashTreeParser#callLocusInfoUpdateCallback --> ".concat(_this1.debugId, " Filtering out update for ").concat(type, ":").concat(id, " v").concat(version, " because dataset \"").concat(dataSetName, "\" has v").concat(existingVersion));
|
|
1260
1308
|
return false;
|
|
1261
1309
|
}
|
|
1262
1310
|
} else if (existingVersion >= version) {
|
|
1263
1311
|
// For removals: filter out if the object still exists in any dataset
|
|
1264
|
-
_loggerProxy.default.logger.info("HashTreeParser#callLocusInfoUpdateCallback --> ".concat(
|
|
1312
|
+
_loggerProxy.default.logger.info("HashTreeParser#callLocusInfoUpdateCallback --> ".concat(_this1.debugId, " Filtering out removal for ").concat(type, ":").concat(id, " v").concat(version, " because dataset \"").concat(dataSetName, "\" still has v").concat(existingVersion));
|
|
1265
1313
|
return false;
|
|
1266
1314
|
}
|
|
1267
1315
|
}
|
|
@@ -1270,13 +1318,14 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1270
1318
|
return true;
|
|
1271
1319
|
});
|
|
1272
1320
|
if (filteredUpdates.length > 0) {
|
|
1273
|
-
this.locusInfoUpdateCallback(
|
|
1321
|
+
this.locusInfoUpdateCallback({
|
|
1322
|
+
updateType: updateType,
|
|
1274
1323
|
updatedObjects: filteredUpdates
|
|
1275
1324
|
});
|
|
1276
1325
|
}
|
|
1277
1326
|
} else if (updateType !== LocusInfoUpdateType.OBJECTS_UPDATED) {
|
|
1278
|
-
this.locusInfoUpdateCallback(
|
|
1279
|
-
|
|
1327
|
+
this.locusInfoUpdateCallback({
|
|
1328
|
+
updateType: updateType
|
|
1280
1329
|
});
|
|
1281
1330
|
}
|
|
1282
1331
|
}
|
|
@@ -1300,102 +1349,342 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1300
1349
|
* Performs a sync for the given data set.
|
|
1301
1350
|
*
|
|
1302
1351
|
* @param {InternalDataSet} dataSet - The data set to sync
|
|
1303
|
-
* @param {string} rootHash - Our current root hash for this data set
|
|
1304
1352
|
* @param {string} reason - The reason for the sync (used for logging)
|
|
1353
|
+
* @param {boolean} [isInitialization] - Whether this is an initialization sync (sends empty leaves data instead of comparing hashes)
|
|
1305
1354
|
* @returns {Promise<void>}
|
|
1306
1355
|
*/
|
|
1307
1356
|
}, {
|
|
1308
1357
|
key: "performSync",
|
|
1309
1358
|
value: (function () {
|
|
1310
|
-
var _performSync = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function
|
|
1311
|
-
var
|
|
1312
|
-
|
|
1313
|
-
|
|
1359
|
+
var _performSync = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee6(dataSet, reason, isInitialization) {
|
|
1360
|
+
var _dataSet$syncAbortCon;
|
|
1361
|
+
var abortController, hashTree, rootHash, leavesData, receivedHashes, hashesResult, mismatchedLeaveIndexes, syncResponse, _t3, _t4;
|
|
1362
|
+
return _regenerator.default.wrap(function (_context7) {
|
|
1363
|
+
while (1) switch (_context7.prev = _context7.next) {
|
|
1314
1364
|
case 0:
|
|
1315
1365
|
if (dataSet.hashTree) {
|
|
1316
|
-
|
|
1366
|
+
_context7.next = 1;
|
|
1317
1367
|
break;
|
|
1318
1368
|
}
|
|
1319
|
-
return
|
|
1369
|
+
return _context7.abrupt("return");
|
|
1320
1370
|
case 1:
|
|
1321
|
-
|
|
1371
|
+
abortController = (_dataSet$syncAbortCon = dataSet.syncAbortController) !== null && _dataSet$syncAbortCon !== void 0 ? _dataSet$syncAbortCon : new AbortController();
|
|
1372
|
+
dataSet.syncAbortController = abortController;
|
|
1373
|
+
hashTree = dataSet.hashTree;
|
|
1374
|
+
rootHash = hashTree.getRootHash();
|
|
1375
|
+
_context7.prev = 2;
|
|
1322
1376
|
_loggerProxy.default.logger.info("HashTreeParser#performSync --> ".concat(this.debugId, " ").concat(reason, ", syncing data set \"").concat(dataSet.name, "\""));
|
|
1323
|
-
|
|
1377
|
+
leavesData = {};
|
|
1378
|
+
if (isInitialization) {
|
|
1379
|
+
_context7.next = 10;
|
|
1380
|
+
break;
|
|
1381
|
+
}
|
|
1324
1382
|
if (!(dataSet.leafCount !== 1)) {
|
|
1325
|
-
|
|
1383
|
+
_context7.next = 9;
|
|
1326
1384
|
break;
|
|
1327
1385
|
}
|
|
1328
|
-
|
|
1329
|
-
|
|
1386
|
+
_context7.prev = 3;
|
|
1387
|
+
_context7.next = 4;
|
|
1330
1388
|
return this.getHashesFromLocus(dataSet.name, rootHash);
|
|
1331
|
-
case 3:
|
|
1332
|
-
_yield$this$getHashes = _context6.sent;
|
|
1333
|
-
hashes = _yield$this$getHashes.hashes;
|
|
1334
|
-
latestDataSetInfo = _yield$this$getHashes.dataSet;
|
|
1335
|
-
receivedHashes = hashes;
|
|
1336
|
-
dataSet.hashTree.resize(latestDataSetInfo.leafCount);
|
|
1337
|
-
_context6.next = 6;
|
|
1338
|
-
break;
|
|
1339
1389
|
case 4:
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1390
|
+
hashesResult = _context7.sent;
|
|
1391
|
+
if (hashesResult) {
|
|
1392
|
+
_context7.next = 5;
|
|
1393
|
+
break;
|
|
1394
|
+
}
|
|
1395
|
+
return _context7.abrupt("return");
|
|
1396
|
+
case 5:
|
|
1397
|
+
receivedHashes = hashesResult.hashes;
|
|
1398
|
+
this.updateDataSetLeafCount(dataSet, hashesResult.dataSet.leafCount);
|
|
1399
|
+
_context7.next = 8;
|
|
1400
|
+
break;
|
|
1401
|
+
case 6:
|
|
1402
|
+
_context7.prev = 6;
|
|
1403
|
+
_t3 = _context7["catch"](3);
|
|
1404
|
+
if (!((_t3 === null || _t3 === void 0 ? void 0 : _t3.statusCode) === 409)) {
|
|
1405
|
+
_context7.next = 7;
|
|
1344
1406
|
break;
|
|
1345
1407
|
}
|
|
1346
1408
|
// this is a leaf count mismatch, we should do nothing, just wait for another heartbeat message from Locus
|
|
1347
1409
|
_loggerProxy.default.logger.info("HashTreeParser#getHashesFromLocus --> ".concat(this.debugId, " Got 409 when fetching hashes for data set \"").concat(dataSet.name, "\": ").concat(_t3.message));
|
|
1348
|
-
return
|
|
1349
|
-
case
|
|
1410
|
+
return _context7.abrupt("return");
|
|
1411
|
+
case 7:
|
|
1350
1412
|
throw _t3;
|
|
1351
|
-
case
|
|
1413
|
+
case 8:
|
|
1352
1414
|
// identify mismatched leaves
|
|
1353
|
-
mismatchedLeaveIndexes =
|
|
1415
|
+
mismatchedLeaveIndexes = hashTree.diffHashes(receivedHashes);
|
|
1354
1416
|
mismatchedLeaveIndexes.forEach(function (index) {
|
|
1355
|
-
|
|
1417
|
+
leavesData[index] = hashTree.getLeafData(index);
|
|
1356
1418
|
});
|
|
1357
|
-
|
|
1419
|
+
_context7.next = 10;
|
|
1358
1420
|
break;
|
|
1359
|
-
case
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1421
|
+
case 9:
|
|
1422
|
+
leavesData = {
|
|
1423
|
+
0: hashTree.getLeafData(0)
|
|
1424
|
+
};
|
|
1425
|
+
case 10:
|
|
1426
|
+
if (!abortController.signal.aborted) {
|
|
1427
|
+
_context7.next = 11;
|
|
1364
1428
|
break;
|
|
1365
1429
|
}
|
|
1366
|
-
|
|
1367
|
-
return
|
|
1368
|
-
case
|
|
1369
|
-
|
|
1430
|
+
_loggerProxy.default.logger.info("HashTreeParser#performSync --> ".concat(this.debugId, " abandoning sync for \"").concat(dataSet.name, "\" before /sync - message received during sync"));
|
|
1431
|
+
return _context7.abrupt("return");
|
|
1432
|
+
case 11:
|
|
1433
|
+
// request sync for mismatched leaves
|
|
1434
|
+
syncResponse = null;
|
|
1435
|
+
if (!isInitialization) {
|
|
1436
|
+
_context7.next = 13;
|
|
1437
|
+
break;
|
|
1438
|
+
}
|
|
1439
|
+
_context7.next = 12;
|
|
1440
|
+
return this.sendSyncRequestToLocus(dataSet, {
|
|
1441
|
+
isInitialization: true
|
|
1442
|
+
});
|
|
1443
|
+
case 12:
|
|
1444
|
+
syncResponse = _context7.sent;
|
|
1445
|
+
_context7.next = 15;
|
|
1446
|
+
break;
|
|
1447
|
+
case 13:
|
|
1448
|
+
if (!((0, _keys.default)(leavesData).length > 0)) {
|
|
1449
|
+
_context7.next = 15;
|
|
1450
|
+
break;
|
|
1451
|
+
}
|
|
1452
|
+
_context7.next = 14;
|
|
1453
|
+
return this.sendSyncRequestToLocus(dataSet, {
|
|
1454
|
+
mismatchedLeavesData: leavesData
|
|
1455
|
+
});
|
|
1456
|
+
case 14:
|
|
1457
|
+
syncResponse = _context7.sent;
|
|
1458
|
+
case 15:
|
|
1370
1459
|
// sync API may return nothing (in that case data will arrive via messages)
|
|
1371
1460
|
// or it may return a response in the same format as messages
|
|
1461
|
+
// We still need to restart the sync timer as a safety net in case the messages don't arrive.
|
|
1462
|
+
this.runSyncAlgorithm(dataSet);
|
|
1372
1463
|
if (syncResponse) {
|
|
1464
|
+
// clear the abort controller before processing the response so that
|
|
1465
|
+
// parseMessage() -> cancelPendingSyncsForDataSets() doesn't log a
|
|
1466
|
+
// misleading "aborting sync" message for this already-completed sync
|
|
1467
|
+
dataSet.syncAbortController = undefined;
|
|
1468
|
+
// the format of sync response is the same as messages, so we can reuse the same handler
|
|
1373
1469
|
this.handleMessage(syncResponse, 'via sync API');
|
|
1374
1470
|
}
|
|
1375
|
-
|
|
1376
|
-
_context6.next = 12;
|
|
1471
|
+
_context7.next = 17;
|
|
1377
1472
|
break;
|
|
1378
|
-
case
|
|
1379
|
-
|
|
1380
|
-
_t4 =
|
|
1381
|
-
if (_t4
|
|
1382
|
-
this.callLocusInfoUpdateCallback({
|
|
1383
|
-
updateType: LocusInfoUpdateType.MEETING_ENDED
|
|
1384
|
-
});
|
|
1385
|
-
} else {
|
|
1473
|
+
case 16:
|
|
1474
|
+
_context7.prev = 16;
|
|
1475
|
+
_t4 = _context7["catch"](2);
|
|
1476
|
+
if (!this.handleSyncErrors(_t4)) {
|
|
1386
1477
|
_loggerProxy.default.logger.warn("HashTreeParser#performSync --> ".concat(this.debugId, " error during sync for data set \"").concat(dataSet.name, "\":"), _t4);
|
|
1387
1478
|
}
|
|
1388
|
-
case
|
|
1479
|
+
case 17:
|
|
1480
|
+
_context7.prev = 17;
|
|
1481
|
+
dataSet.syncAbortController = undefined;
|
|
1482
|
+
return _context7.finish(17);
|
|
1483
|
+
case 18:
|
|
1389
1484
|
case "end":
|
|
1390
|
-
return
|
|
1485
|
+
return _context7.stop();
|
|
1391
1486
|
}
|
|
1392
|
-
},
|
|
1487
|
+
}, _callee6, this, [[2, 16, 17, 18], [3, 6]]);
|
|
1393
1488
|
}));
|
|
1394
|
-
function performSync(
|
|
1489
|
+
function performSync(_x8, _x9, _x0) {
|
|
1395
1490
|
return _performSync.apply(this, arguments);
|
|
1396
1491
|
}
|
|
1397
1492
|
return performSync;
|
|
1398
1493
|
}()
|
|
1494
|
+
/**
|
|
1495
|
+
* Cancels any pending or in-flight syncs for the specified data sets.
|
|
1496
|
+
* This removes matching entries from the sync queue and aborts any in-flight sync HTTP requests.
|
|
1497
|
+
*
|
|
1498
|
+
* @param {string[]} dataSetNames - The names of the data sets to cancel syncs for
|
|
1499
|
+
* @returns {void}
|
|
1500
|
+
*/
|
|
1501
|
+
)
|
|
1502
|
+
}, {
|
|
1503
|
+
key: "cancelPendingSyncsForDataSets",
|
|
1504
|
+
value: function cancelPendingSyncsForDataSets(dataSetNames) {
|
|
1505
|
+
var previousLength = this.syncQueue.length;
|
|
1506
|
+
this.syncQueue = this.syncQueue.filter(function (entry) {
|
|
1507
|
+
return !dataSetNames.includes(entry.dataSetName);
|
|
1508
|
+
});
|
|
1509
|
+
if (previousLength !== this.syncQueue.length) {
|
|
1510
|
+
_loggerProxy.default.logger.info("HashTreeParser#cancelPendingSyncsForDataSets --> ".concat(this.debugId, " removed ").concat(previousLength - this.syncQueue.length, " entries from sync queue for data sets: ").concat(dataSetNames.join(', ')));
|
|
1511
|
+
}
|
|
1512
|
+
var _iterator9 = _createForOfIteratorHelper(dataSetNames),
|
|
1513
|
+
_step9;
|
|
1514
|
+
try {
|
|
1515
|
+
for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
|
|
1516
|
+
var _this$dataSets$name;
|
|
1517
|
+
var name = _step9.value;
|
|
1518
|
+
if ((_this$dataSets$name = this.dataSets[name]) !== null && _this$dataSets$name !== void 0 && _this$dataSets$name.syncAbortController) {
|
|
1519
|
+
_loggerProxy.default.logger.info("HashTreeParser#cancelPendingSyncsForDataSets --> ".concat(this.debugId, " aborting in-flight sync for data set \"").concat(name, "\""));
|
|
1520
|
+
this.dataSets[name].syncAbortController.abort();
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1523
|
+
} catch (err) {
|
|
1524
|
+
_iterator9.e(err);
|
|
1525
|
+
} finally {
|
|
1526
|
+
_iterator9.f();
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
|
|
1530
|
+
/**
|
|
1531
|
+
* Enqueues a sync for the given data set. If the data set is already in the queue, the request is ignored.
|
|
1532
|
+
* This ensures that all syncs are executed sequentially and no more than 1 sync runs at a time.
|
|
1533
|
+
*
|
|
1534
|
+
* @param {string} dataSetName - The name of the data set to sync
|
|
1535
|
+
* @param {string} reason - The reason for the sync (used for logging)
|
|
1536
|
+
* @param {boolean} [isInitialization=false] - Whether this is an initialization sync (uses empty leaves data instead of hash comparison)
|
|
1537
|
+
* @returns {void}
|
|
1538
|
+
*/
|
|
1539
|
+
}, {
|
|
1540
|
+
key: "enqueueSyncForDataset",
|
|
1541
|
+
value: function enqueueSyncForDataset(dataSetName, reason) {
|
|
1542
|
+
var isInitialization = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
1543
|
+
if (this.state === 'stopped') return;
|
|
1544
|
+
var existingEntry = this.syncQueue.find(function (entry) {
|
|
1545
|
+
return entry.dataSetName === dataSetName;
|
|
1546
|
+
});
|
|
1547
|
+
if (existingEntry) {
|
|
1548
|
+
if (isInitialization) {
|
|
1549
|
+
existingEntry.isInitialization = true;
|
|
1550
|
+
}
|
|
1551
|
+
_loggerProxy.default.logger.info("HashTreeParser#enqueueSyncForDataset --> ".concat(this.debugId, " data set \"").concat(dataSetName, "\" already in sync queue, skipping"));
|
|
1552
|
+
return;
|
|
1553
|
+
}
|
|
1554
|
+
this.syncQueue.push({
|
|
1555
|
+
dataSetName: dataSetName,
|
|
1556
|
+
reason: reason,
|
|
1557
|
+
isInitialization: isInitialization
|
|
1558
|
+
});
|
|
1559
|
+
if (!this.isSyncInProgress) {
|
|
1560
|
+
this.syncQueueProcessingPromise = this.processSyncQueue();
|
|
1561
|
+
}
|
|
1562
|
+
}
|
|
1563
|
+
|
|
1564
|
+
/**
|
|
1565
|
+
* Processes the sync queue sequentially. Only one instance of this method runs at a time.
|
|
1566
|
+
*
|
|
1567
|
+
* @returns {Promise<void>}
|
|
1568
|
+
*/
|
|
1569
|
+
}, {
|
|
1570
|
+
key: "processSyncQueue",
|
|
1571
|
+
value: (function () {
|
|
1572
|
+
var _processSyncQueue = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee7() {
|
|
1573
|
+
var _ref8, dataSetName, reason, isInitialization, dataSet;
|
|
1574
|
+
return _regenerator.default.wrap(function (_context8) {
|
|
1575
|
+
while (1) switch (_context8.prev = _context8.next) {
|
|
1576
|
+
case 0:
|
|
1577
|
+
if (!this.isSyncInProgress) {
|
|
1578
|
+
_context8.next = 1;
|
|
1579
|
+
break;
|
|
1580
|
+
}
|
|
1581
|
+
return _context8.abrupt("return");
|
|
1582
|
+
case 1:
|
|
1583
|
+
this.isSyncInProgress = true;
|
|
1584
|
+
_context8.prev = 2;
|
|
1585
|
+
case 3:
|
|
1586
|
+
if (!(this.syncQueue.length > 0 && this.state !== 'stopped')) {
|
|
1587
|
+
_context8.next = 6;
|
|
1588
|
+
break;
|
|
1589
|
+
}
|
|
1590
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
1591
|
+
_ref8 = this.syncQueue.shift(), dataSetName = _ref8.dataSetName, reason = _ref8.reason, isInitialization = _ref8.isInitialization;
|
|
1592
|
+
dataSet = this.dataSets[dataSetName];
|
|
1593
|
+
if (dataSet !== null && dataSet !== void 0 && dataSet.hashTree) {
|
|
1594
|
+
_context8.next = 4;
|
|
1595
|
+
break;
|
|
1596
|
+
}
|
|
1597
|
+
return _context8.abrupt("continue", 3);
|
|
1598
|
+
case 4:
|
|
1599
|
+
_context8.next = 5;
|
|
1600
|
+
return this.performSync(dataSet, reason, isInitialization);
|
|
1601
|
+
case 5:
|
|
1602
|
+
_context8.next = 3;
|
|
1603
|
+
break;
|
|
1604
|
+
case 6:
|
|
1605
|
+
_context8.prev = 6;
|
|
1606
|
+
this.isSyncInProgress = false;
|
|
1607
|
+
return _context8.finish(6);
|
|
1608
|
+
case 7:
|
|
1609
|
+
case "end":
|
|
1610
|
+
return _context8.stop();
|
|
1611
|
+
}
|
|
1612
|
+
}, _callee7, this, [[2,, 6, 7]]);
|
|
1613
|
+
}));
|
|
1614
|
+
function processSyncQueue() {
|
|
1615
|
+
return _processSyncQueue.apply(this, arguments);
|
|
1616
|
+
}
|
|
1617
|
+
return processSyncQueue;
|
|
1618
|
+
}()
|
|
1619
|
+
/**
|
|
1620
|
+
* Syncs all data sets that have hash trees, one by one in sequence, using the priority order
|
|
1621
|
+
* provided by sortByInitPriority(). Does nothing if the parser is stopped or if a syncAllDatasets
|
|
1622
|
+
* call is already in progress.
|
|
1623
|
+
*
|
|
1624
|
+
* @returns {Promise<void>}
|
|
1625
|
+
*/
|
|
1626
|
+
)
|
|
1627
|
+
}, {
|
|
1628
|
+
key: "syncAllDatasets",
|
|
1629
|
+
value: (function () {
|
|
1630
|
+
var _syncAllDatasets = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee8() {
|
|
1631
|
+
var dataSetsWithHashTrees, sorted, _iterator0, _step0, ds;
|
|
1632
|
+
return _regenerator.default.wrap(function (_context9) {
|
|
1633
|
+
while (1) switch (_context9.prev = _context9.next) {
|
|
1634
|
+
case 0:
|
|
1635
|
+
if (!(this.state === 'stopped')) {
|
|
1636
|
+
_context9.next = 1;
|
|
1637
|
+
break;
|
|
1638
|
+
}
|
|
1639
|
+
return _context9.abrupt("return");
|
|
1640
|
+
case 1:
|
|
1641
|
+
if (!this.isSyncAllInProgress) {
|
|
1642
|
+
_context9.next = 2;
|
|
1643
|
+
break;
|
|
1644
|
+
}
|
|
1645
|
+
return _context9.abrupt("return");
|
|
1646
|
+
case 2:
|
|
1647
|
+
this.isSyncAllInProgress = true;
|
|
1648
|
+
_context9.prev = 3;
|
|
1649
|
+
dataSetsWithHashTrees = (0, _values.default)(this.dataSets).filter(function (dataSet) {
|
|
1650
|
+
return dataSet === null || dataSet === void 0 ? void 0 : dataSet.hashTree;
|
|
1651
|
+
}).map(function (dataSet) {
|
|
1652
|
+
return {
|
|
1653
|
+
name: dataSet.name
|
|
1654
|
+
};
|
|
1655
|
+
});
|
|
1656
|
+
sorted = (0, _utils.sortByInitPriority)(dataSetsWithHashTrees, _constants3.DATA_SET_INIT_PRIORITY);
|
|
1657
|
+
_loggerProxy.default.logger.info("HashTreeParser#syncAllDatasets --> ".concat(this.debugId, " syncing datasets: ").concat(sorted.map(function (ds) {
|
|
1658
|
+
return ds.name;
|
|
1659
|
+
}).join(', ')));
|
|
1660
|
+
_iterator0 = _createForOfIteratorHelper(sorted);
|
|
1661
|
+
try {
|
|
1662
|
+
for (_iterator0.s(); !(_step0 = _iterator0.n()).done;) {
|
|
1663
|
+
ds = _step0.value;
|
|
1664
|
+
this.enqueueSyncForDataset(ds.name, 'syncAllDatasets');
|
|
1665
|
+
}
|
|
1666
|
+
} catch (err) {
|
|
1667
|
+
_iterator0.e(err);
|
|
1668
|
+
} finally {
|
|
1669
|
+
_iterator0.f();
|
|
1670
|
+
}
|
|
1671
|
+
_context9.next = 4;
|
|
1672
|
+
return this.syncQueueProcessingPromise;
|
|
1673
|
+
case 4:
|
|
1674
|
+
_context9.prev = 4;
|
|
1675
|
+
this.isSyncAllInProgress = false;
|
|
1676
|
+
return _context9.finish(4);
|
|
1677
|
+
case 5:
|
|
1678
|
+
case "end":
|
|
1679
|
+
return _context9.stop();
|
|
1680
|
+
}
|
|
1681
|
+
}, _callee8, this, [[3,, 4, 5]]);
|
|
1682
|
+
}));
|
|
1683
|
+
function syncAllDatasets() {
|
|
1684
|
+
return _syncAllDatasets.apply(this, arguments);
|
|
1685
|
+
}
|
|
1686
|
+
return syncAllDatasets;
|
|
1687
|
+
}()
|
|
1399
1688
|
/**
|
|
1400
1689
|
* Runs the sync algorithm for the given data set.
|
|
1401
1690
|
*
|
|
@@ -1406,58 +1695,35 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1406
1695
|
}, {
|
|
1407
1696
|
key: "runSyncAlgorithm",
|
|
1408
1697
|
value: function runSyncAlgorithm(receivedDataSet) {
|
|
1409
|
-
var
|
|
1698
|
+
var _this10 = this;
|
|
1410
1699
|
var dataSet = this.dataSets[receivedDataSet.name];
|
|
1411
1700
|
if (!dataSet) {
|
|
1412
1701
|
_loggerProxy.default.logger.warn("HashTreeParser#runSyncAlgorithm --> ".concat(this.debugId, " No data set found for ").concat(receivedDataSet.name, ", skipping sync algorithm"));
|
|
1413
1702
|
return;
|
|
1414
1703
|
}
|
|
1415
1704
|
if (!dataSet.hashTree) {
|
|
1416
|
-
|
|
1705
|
+
// no hash tree, so no need to do any syncing
|
|
1706
|
+
// we fall into this branch often, because Locus sends dataSets in messages that are not visible to us
|
|
1707
|
+
|
|
1417
1708
|
return;
|
|
1418
1709
|
}
|
|
1419
1710
|
dataSet.hashTree.resize(receivedDataSet.leafCount);
|
|
1420
|
-
|
|
1421
|
-
// temporary log for the workshop // todo: remove
|
|
1422
|
-
var ourCurrentRootHash = dataSet.hashTree.getRootHash();
|
|
1423
|
-
_loggerProxy.default.logger.info("HashTreeParser#runSyncAlgorithm --> ".concat(this.debugId, " dataSet=\"").concat(dataSet.name, "\" version=").concat(dataSet.version, " hashes before starting timer: ours=").concat(ourCurrentRootHash, " Locus=").concat(dataSet.root));
|
|
1424
1711
|
var delay = dataSet.idleMs + this.getWeightedBackoffTime(dataSet.backoff);
|
|
1425
1712
|
if (delay > 0) {
|
|
1426
1713
|
if (dataSet.timer) {
|
|
1427
1714
|
clearTimeout(dataSet.timer);
|
|
1428
1715
|
}
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
_loggerProxy.default.logger.warn("HashTreeParser#runSyncAlgorithm --> ".concat(_this11.debugId, " Data set \"").concat(dataSet.name, "\" no longer has a hash tree, cannot run sync algorithm"));
|
|
1441
|
-
return _context7.abrupt("return");
|
|
1442
|
-
case 1:
|
|
1443
|
-
rootHash = dataSet.hashTree.getRootHash();
|
|
1444
|
-
if (!(dataSet.root !== rootHash)) {
|
|
1445
|
-
_context7.next = 3;
|
|
1446
|
-
break;
|
|
1447
|
-
}
|
|
1448
|
-
_context7.next = 2;
|
|
1449
|
-
return _this11.performSync(dataSet, rootHash, "Root hash mismatch: received=".concat(dataSet.root, ", ours=").concat(rootHash));
|
|
1450
|
-
case 2:
|
|
1451
|
-
_context7.next = 4;
|
|
1452
|
-
break;
|
|
1453
|
-
case 3:
|
|
1454
|
-
_loggerProxy.default.logger.info("HashTreeParser#runSyncAlgorithm --> ".concat(_this11.debugId, " \"").concat(dataSet.name, "\" root hash matching: ").concat(rootHash, ", version=").concat(dataSet.version));
|
|
1455
|
-
case 4:
|
|
1456
|
-
case "end":
|
|
1457
|
-
return _context7.stop();
|
|
1458
|
-
}
|
|
1459
|
-
}, _callee6);
|
|
1460
|
-
})), delay);
|
|
1716
|
+
dataSet.timer = setTimeout(function () {
|
|
1717
|
+
dataSet.timer = undefined;
|
|
1718
|
+
if (!dataSet.hashTree) {
|
|
1719
|
+
_loggerProxy.default.logger.warn("HashTreeParser#runSyncAlgorithm --> ".concat(_this10.debugId, " Data set \"").concat(dataSet.name, "\" no longer has a hash tree, cannot run sync algorithm"));
|
|
1720
|
+
return;
|
|
1721
|
+
}
|
|
1722
|
+
var rootHash = dataSet.hashTree.getRootHash();
|
|
1723
|
+
if (dataSet.root !== rootHash) {
|
|
1724
|
+
_this10.enqueueSyncForDataset(dataSet.name, "Root hash mismatch: received=".concat(dataSet.root, ", ours=").concat(rootHash));
|
|
1725
|
+
}
|
|
1726
|
+
}, delay);
|
|
1461
1727
|
} else {
|
|
1462
1728
|
_loggerProxy.default.logger.info("HashTreeParser#runSyncAlgorithm --> ".concat(this.debugId, " No delay for \"").concat(dataSet.name, "\" data set, skipping sync timer reset/setup"));
|
|
1463
1729
|
}
|
|
@@ -1475,16 +1741,16 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1475
1741
|
}, {
|
|
1476
1742
|
key: "resetHeartbeatWatchdogs",
|
|
1477
1743
|
value: function resetHeartbeatWatchdogs(receivedDataSets) {
|
|
1478
|
-
var
|
|
1744
|
+
var _this11 = this;
|
|
1479
1745
|
if (!this.heartbeatIntervalMs) {
|
|
1480
1746
|
return;
|
|
1481
1747
|
}
|
|
1482
|
-
var
|
|
1483
|
-
|
|
1748
|
+
var _iterator1 = _createForOfIteratorHelper(receivedDataSets),
|
|
1749
|
+
_step1;
|
|
1484
1750
|
try {
|
|
1485
1751
|
var _loop2 = function _loop2() {
|
|
1486
|
-
var receivedDataSet =
|
|
1487
|
-
var dataSet =
|
|
1752
|
+
var receivedDataSet = _step1.value;
|
|
1753
|
+
var dataSet = _this11.dataSets[receivedDataSet.name];
|
|
1488
1754
|
if (!(dataSet !== null && dataSet !== void 0 && dataSet.hashTree)) {
|
|
1489
1755
|
// eslint-disable-next-line no-continue
|
|
1490
1756
|
return 1; // continue
|
|
@@ -1493,30 +1759,26 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1493
1759
|
clearTimeout(dataSet.heartbeatWatchdogTimer);
|
|
1494
1760
|
dataSet.heartbeatWatchdogTimer = undefined;
|
|
1495
1761
|
}
|
|
1496
|
-
var backoffTime =
|
|
1497
|
-
var delay =
|
|
1498
|
-
dataSet.heartbeatWatchdogTimer = setTimeout(
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
return _context8.stop();
|
|
1509
|
-
}
|
|
1510
|
-
}, _callee7);
|
|
1511
|
-
})), delay);
|
|
1762
|
+
var backoffTime = _this11.getWeightedBackoffTime(dataSet.backoff);
|
|
1763
|
+
var delay = _this11.heartbeatIntervalMs + backoffTime;
|
|
1764
|
+
dataSet.heartbeatWatchdogTimer = setTimeout(function () {
|
|
1765
|
+
dataSet.heartbeatWatchdogTimer = undefined;
|
|
1766
|
+
_loggerProxy.default.logger.warn("HashTreeParser#resetHeartbeatWatchdogs --> ".concat(_this11.debugId, " Heartbeat watchdog fired for data set \"").concat(dataSet.name, "\" - no heartbeat received within expected interval, initiating sync"));
|
|
1767
|
+
_metrics.default.sendBehavioralMetric(_constants.default.HASH_TREE_HEARTBEAT_WATCHDOG_EXPIRED, {
|
|
1768
|
+
debugId: _this11.debugId,
|
|
1769
|
+
dataSetName: dataSet.name
|
|
1770
|
+
});
|
|
1771
|
+
_this11.enqueueSyncForDataset(dataSet.name, "heartbeat watchdog expired");
|
|
1772
|
+
_this11.resetHeartbeatWatchdogs([dataSet]);
|
|
1773
|
+
}, delay);
|
|
1512
1774
|
};
|
|
1513
|
-
for (
|
|
1775
|
+
for (_iterator1.s(); !(_step1 = _iterator1.n()).done;) {
|
|
1514
1776
|
if (_loop2()) continue;
|
|
1515
1777
|
}
|
|
1516
1778
|
} catch (err) {
|
|
1517
|
-
|
|
1779
|
+
_iterator1.e(err);
|
|
1518
1780
|
} finally {
|
|
1519
|
-
|
|
1781
|
+
_iterator1.f();
|
|
1520
1782
|
}
|
|
1521
1783
|
}
|
|
1522
1784
|
|
|
@@ -1550,7 +1812,11 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1550
1812
|
value: function stop() {
|
|
1551
1813
|
_loggerProxy.default.logger.info("HashTreeParser#stop --> ".concat(this.debugId, " Stopping HashTreeParser, clearing timers and hash trees"));
|
|
1552
1814
|
this.stopAllTimers();
|
|
1815
|
+
this.syncQueue = [];
|
|
1553
1816
|
(0, _values.default)(this.dataSets).forEach(function (dataSet) {
|
|
1817
|
+
var _dataSet$syncAbortCon2;
|
|
1818
|
+
(_dataSet$syncAbortCon2 = dataSet.syncAbortController) === null || _dataSet$syncAbortCon2 === void 0 ? void 0 : _dataSet$syncAbortCon2.abort();
|
|
1819
|
+
dataSet.syncAbortController = undefined;
|
|
1554
1820
|
dataSet.hashTree = undefined;
|
|
1555
1821
|
});
|
|
1556
1822
|
this.visibleDataSets = [];
|
|
@@ -1558,29 +1824,41 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1558
1824
|
}
|
|
1559
1825
|
|
|
1560
1826
|
/**
|
|
1561
|
-
*
|
|
1827
|
+
* Cleans up the HashTreeParser, stopping all timers and clearing all internal state.
|
|
1828
|
+
* After calling this, the parser should not be used anymore.
|
|
1829
|
+
* @returns {void}
|
|
1830
|
+
*/
|
|
1831
|
+
}, {
|
|
1832
|
+
key: "cleanUp",
|
|
1833
|
+
value: function cleanUp() {
|
|
1834
|
+
this.stop();
|
|
1835
|
+
this.dataSets = {};
|
|
1836
|
+
}
|
|
1837
|
+
|
|
1838
|
+
/**
|
|
1839
|
+
* Resumes the HashTreeParser that was previously stopped, using a hash tree message.
|
|
1562
1840
|
* @param {HashTreeMessage} message - The message to resume with, it must contain metadata with visible data sets info
|
|
1563
1841
|
* @returns {void}
|
|
1564
1842
|
*/
|
|
1565
1843
|
}, {
|
|
1566
|
-
key: "
|
|
1567
|
-
value: function
|
|
1844
|
+
key: "resumeFromMessage",
|
|
1845
|
+
value: function resumeFromMessage(message) {
|
|
1568
1846
|
var _message$locusStateEl3, _metadataObject$data;
|
|
1569
1847
|
// check that message contains metadata with visible data sets - this is essential to be able to resume
|
|
1570
1848
|
var metadataObject = (_message$locusStateEl3 = message.locusStateElements) === null || _message$locusStateEl3 === void 0 ? void 0 : _message$locusStateEl3.find(function (el) {
|
|
1571
1849
|
return (0, _utils.isMetadata)(el);
|
|
1572
1850
|
});
|
|
1573
1851
|
if (!(metadataObject !== null && metadataObject !== void 0 && (_metadataObject$data = metadataObject.data) !== null && _metadataObject$data !== void 0 && _metadataObject$data.visibleDataSets)) {
|
|
1574
|
-
_loggerProxy.default.logger.warn("HashTreeParser#
|
|
1852
|
+
_loggerProxy.default.logger.warn("HashTreeParser#resumeFromMessage --> ".concat(this.debugId, " Cannot resume HashTreeParser because the message is missing metadata with visible data sets info"));
|
|
1575
1853
|
return;
|
|
1576
1854
|
}
|
|
1577
1855
|
this.setVisibleDataSets(metadataObject.data.visibleDataSets, message.dataSets);
|
|
1578
1856
|
this.dataSets = {};
|
|
1579
|
-
var
|
|
1580
|
-
|
|
1857
|
+
var _iterator10 = _createForOfIteratorHelper(message.dataSets),
|
|
1858
|
+
_step10;
|
|
1581
1859
|
try {
|
|
1582
|
-
for (
|
|
1583
|
-
var dataSet =
|
|
1860
|
+
for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {
|
|
1861
|
+
var dataSet = _step10.value;
|
|
1584
1862
|
var name = dataSet.name,
|
|
1585
1863
|
leafCount = dataSet.leafCount;
|
|
1586
1864
|
this.dataSets[name] = _objectSpread(_objectSpread({}, dataSet), {}, {
|
|
@@ -1588,23 +1866,62 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1588
1866
|
});
|
|
1589
1867
|
}
|
|
1590
1868
|
} catch (err) {
|
|
1591
|
-
|
|
1869
|
+
_iterator10.e(err);
|
|
1592
1870
|
} finally {
|
|
1593
|
-
|
|
1871
|
+
_iterator10.f();
|
|
1594
1872
|
}
|
|
1595
|
-
_loggerProxy.default.logger.info("HashTreeParser#
|
|
1873
|
+
_loggerProxy.default.logger.info("HashTreeParser#resumeFromMessage --> ".concat(this.debugId, " Resuming HashTreeParser with data sets: ").concat((0, _keys.default)(this.dataSets).join(', '), ", visible data sets: ").concat(this.visibleDataSets.map(function (ds) {
|
|
1596
1874
|
return ds.name;
|
|
1597
1875
|
}).join(', ')));
|
|
1598
1876
|
this.state = 'active';
|
|
1599
1877
|
this.handleMessage(message, 'on resume');
|
|
1600
1878
|
}
|
|
1879
|
+
|
|
1880
|
+
/**
|
|
1881
|
+
* Resumes the HashTreeParser that was previously stopped, using a Locus API response.
|
|
1882
|
+
* Unlike resumeFromMessage(), this does not require metadata/dataSets in the input,
|
|
1883
|
+
* as it fetches all necessary information from Locus via initializeFromGetLociResponse.
|
|
1884
|
+
* @param {LocusDTO} locus - locus object from an API response
|
|
1885
|
+
* @returns {Promise}
|
|
1886
|
+
*/
|
|
1887
|
+
}, {
|
|
1888
|
+
key: "resumeFromApiResponse",
|
|
1889
|
+
value: (function () {
|
|
1890
|
+
var _resumeFromApiResponse = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee9(locus) {
|
|
1891
|
+
return _regenerator.default.wrap(function (_context0) {
|
|
1892
|
+
while (1) switch (_context0.prev = _context0.next) {
|
|
1893
|
+
case 0:
|
|
1894
|
+
this.state = 'active';
|
|
1895
|
+
this.dataSets = {};
|
|
1896
|
+
_loggerProxy.default.logger.info("HashTreeParser#resumeFromApiResponse --> ".concat(this.debugId, " Resuming HashTreeParser from API response"));
|
|
1897
|
+
_context0.next = 1;
|
|
1898
|
+
return this.initializeFromGetLociResponse(locus);
|
|
1899
|
+
case 1:
|
|
1900
|
+
case "end":
|
|
1901
|
+
return _context0.stop();
|
|
1902
|
+
}
|
|
1903
|
+
}, _callee9, this);
|
|
1904
|
+
}));
|
|
1905
|
+
function resumeFromApiResponse(_x1) {
|
|
1906
|
+
return _resumeFromApiResponse.apply(this, arguments);
|
|
1907
|
+
}
|
|
1908
|
+
return resumeFromApiResponse;
|
|
1909
|
+
}())
|
|
1601
1910
|
}, {
|
|
1602
1911
|
key: "checkForSentinelHttpResponse",
|
|
1603
1912
|
value: function checkForSentinelHttpResponse(error, dataSetName) {
|
|
1604
1913
|
var _error$body;
|
|
1914
|
+
// 404 for any dataset means the locus is no longer available at this URL - could be replaced or ended
|
|
1915
|
+
// if a dataset is just not visible, we would get a 400
|
|
1916
|
+
if (error.statusCode === 404) {
|
|
1917
|
+
_loggerProxy.default.logger.info("HashTreeParser#checkForSentinelHttpResponse --> ".concat(this.debugId, " Received 404 for data set \"").concat(dataSetName, "\", locus not found"));
|
|
1918
|
+
this.stopAllTimers();
|
|
1919
|
+
throw new LocusNotFoundError();
|
|
1920
|
+
}
|
|
1605
1921
|
var isValidDataSetForSentinel = dataSetName === undefined || PossibleSentinelMessageDataSetNames.includes(dataSetName.toLowerCase());
|
|
1606
|
-
if (
|
|
1607
|
-
|
|
1922
|
+
if (error.statusCode === 409 && ((_error$body = error.body) === null || _error$body === void 0 ? void 0 : _error$body.errorCode) === _types2.LocusErrorCodes.LOCUS_INACTIVE && isValidDataSetForSentinel) {
|
|
1923
|
+
var _error$body2;
|
|
1924
|
+
_loggerProxy.default.logger.info("HashTreeParser#checkForSentinelHttpResponse --> ".concat(this.debugId, " Received ").concat(error.statusCode, "/").concat((_error$body2 = error.body) === null || _error$body2 === void 0 ? void 0 : _error$body2.errorCode, " for data set \"").concat(dataSetName, "\", indicating that the meeting has ended"));
|
|
1608
1925
|
this.stopAllTimers();
|
|
1609
1926
|
throw new MeetingEndedError();
|
|
1610
1927
|
}
|
|
@@ -1614,37 +1931,49 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1614
1931
|
* Gets the current hashes from the locus for a specific data set.
|
|
1615
1932
|
* @param {string} dataSetName
|
|
1616
1933
|
* @param {string} currentRootHash
|
|
1617
|
-
* @returns {
|
|
1934
|
+
* @returns {Object|null} An object containing the hashes and leaf count, or null if the hashes match and no sync is needed
|
|
1618
1935
|
*/
|
|
1619
1936
|
}, {
|
|
1620
1937
|
key: "getHashesFromLocus",
|
|
1621
1938
|
value: function getHashesFromLocus(dataSetName, currentRootHash) {
|
|
1622
|
-
var
|
|
1939
|
+
var _this12 = this;
|
|
1623
1940
|
_loggerProxy.default.logger.info("HashTreeParser#getHashesFromLocus --> ".concat(this.debugId, " Requesting hashes for data set \"").concat(dataSetName, "\""));
|
|
1624
1941
|
var dataSet = this.dataSets[dataSetName];
|
|
1625
1942
|
var url = "".concat(dataSet.url, "/hashtree");
|
|
1626
1943
|
return this.webexRequest({
|
|
1627
|
-
method:
|
|
1944
|
+
method: _constants2.HTTP_VERBS.GET,
|
|
1628
1945
|
uri: url,
|
|
1629
1946
|
qs: {
|
|
1630
1947
|
rootHash: currentRootHash
|
|
1631
1948
|
}
|
|
1632
1949
|
}).then(function (response) {
|
|
1633
1950
|
var _response$body, _response$body2;
|
|
1951
|
+
if (!response.body || (0, _lodash.isEmpty)(response.body)) {
|
|
1952
|
+
// 204 with empty body means our hashes match Locus, no sync needed
|
|
1953
|
+
_loggerProxy.default.logger.info("HashTreeParser#getHashesFromLocus --> ".concat(_this12.debugId, " Got ").concat(response.statusCode, " with empty body for data set \"").concat(dataSetName, "\", hashes match - no sync needed"));
|
|
1954
|
+
return null;
|
|
1955
|
+
}
|
|
1634
1956
|
var hashes = (_response$body = response.body) === null || _response$body === void 0 ? void 0 : _response$body.hashes;
|
|
1635
1957
|
var dataSetFromResponse = (_response$body2 = response.body) === null || _response$body2 === void 0 ? void 0 : _response$body2.dataSet;
|
|
1636
1958
|
if (!hashes || !(0, _isArray.default)(hashes)) {
|
|
1637
|
-
_loggerProxy.default.logger.warn("HashTreeParser#getHashesFromLocus --> ".concat(
|
|
1959
|
+
_loggerProxy.default.logger.warn("HashTreeParser#getHashesFromLocus --> ".concat(_this12.debugId, " Locus returned invalid hashes, response body="), response.body);
|
|
1638
1960
|
throw new Error("Locus returned invalid hashes: ".concat(hashes));
|
|
1639
1961
|
}
|
|
1640
|
-
_loggerProxy.default.logger.info("HashTreeParser#getHashesFromLocus --> ".concat(
|
|
1962
|
+
_loggerProxy.default.logger.info("HashTreeParser#getHashesFromLocus --> ".concat(_this12.debugId, " Received hashes for data set \"").concat(dataSetName, "\": ").concat((0, _stringify.default)(hashes)));
|
|
1641
1963
|
return {
|
|
1642
1964
|
hashes: hashes,
|
|
1643
1965
|
dataSet: dataSetFromResponse
|
|
1644
1966
|
};
|
|
1645
1967
|
}).catch(function (error) {
|
|
1646
|
-
_loggerProxy.default.logger.error("HashTreeParser#getHashesFromLocus --> ".concat(
|
|
1647
|
-
|
|
1968
|
+
_loggerProxy.default.logger.error("HashTreeParser#getHashesFromLocus --> ".concat(_this12.debugId, " Error ").concat(error.statusCode, " fetching hashes for data set \"").concat(dataSetName, "\":"), error);
|
|
1969
|
+
_this12.checkForSentinelHttpResponse(error, dataSet.name);
|
|
1970
|
+
_metrics.default.sendBehavioralMetric(_constants.default.HASH_TREE_SYNC_FAILURE, {
|
|
1971
|
+
debugId: _this12.debugId,
|
|
1972
|
+
dataSetName: dataSetName,
|
|
1973
|
+
request: 'GET /hashtree',
|
|
1974
|
+
statusCode: error.statusCode,
|
|
1975
|
+
reason: error.message
|
|
1976
|
+
});
|
|
1648
1977
|
throw error;
|
|
1649
1978
|
});
|
|
1650
1979
|
}
|
|
@@ -1653,43 +1982,60 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1653
1982
|
* Sends a sync request to Locus for the specified data set.
|
|
1654
1983
|
*
|
|
1655
1984
|
* @param {InternalDataSet} dataSet The data set to sync.
|
|
1656
|
-
* @param {
|
|
1985
|
+
* @param {Object} options Either `{ isInitialization: true }` for init syncs (uses leafCount=1 with empty leaf data) or `{ mismatchedLeavesData }` for normal syncs.
|
|
1657
1986
|
* @returns {Promise<HashTreeMessage|null>}
|
|
1658
1987
|
*/
|
|
1659
1988
|
}, {
|
|
1660
1989
|
key: "sendSyncRequestToLocus",
|
|
1661
|
-
value: function sendSyncRequestToLocus(dataSet,
|
|
1662
|
-
var
|
|
1990
|
+
value: function sendSyncRequestToLocus(dataSet, options) {
|
|
1991
|
+
var _this13 = this;
|
|
1663
1992
|
_loggerProxy.default.logger.info("HashTreeParser#sendSyncRequestToLocus --> ".concat(this.debugId, " Sending sync request for data set \"").concat(dataSet.name, "\""));
|
|
1993
|
+
var isInitialization = 'isInitialization' in options;
|
|
1664
1994
|
var url = "".concat(dataSet.url, "/sync");
|
|
1665
1995
|
var body = {
|
|
1666
|
-
leafCount: dataSet.leafCount,
|
|
1996
|
+
leafCount: isInitialization ? 1 : dataSet.leafCount,
|
|
1667
1997
|
leafDataEntries: []
|
|
1668
1998
|
};
|
|
1669
|
-
|
|
1999
|
+
if (isInitialization) {
|
|
2000
|
+
// initialization sync: Locus requires leafCount=1 with a single empty leaf
|
|
1670
2001
|
body.leafDataEntries.push({
|
|
1671
|
-
leafIndex:
|
|
1672
|
-
elementIds:
|
|
2002
|
+
leafIndex: 0,
|
|
2003
|
+
elementIds: []
|
|
1673
2004
|
});
|
|
1674
|
-
}
|
|
1675
|
-
|
|
2005
|
+
} else {
|
|
2006
|
+
var mismatchedLeavesData = options.mismatchedLeavesData;
|
|
2007
|
+
(0, _keys.default)(mismatchedLeavesData).forEach(function (index) {
|
|
2008
|
+
var leafIndex = (0, _parseInt2.default)(index, 10);
|
|
2009
|
+
body.leafDataEntries.push({
|
|
2010
|
+
leafIndex: leafIndex,
|
|
2011
|
+
elementIds: mismatchedLeavesData[leafIndex]
|
|
2012
|
+
});
|
|
2013
|
+
});
|
|
2014
|
+
}
|
|
2015
|
+
var ourCurrentRootHash = dataSet.hashTree ? dataSet.hashTree.getRootHash() : _constants3.EMPTY_HASH;
|
|
1676
2016
|
return this.webexRequest({
|
|
1677
|
-
method:
|
|
2017
|
+
method: _constants2.HTTP_VERBS.POST,
|
|
1678
2018
|
uri: url,
|
|
1679
2019
|
qs: {
|
|
1680
2020
|
rootHash: ourCurrentRootHash
|
|
1681
2021
|
},
|
|
1682
2022
|
body: body
|
|
1683
2023
|
}).then(function (resp) {
|
|
1684
|
-
_loggerProxy.default.logger.info("HashTreeParser#sendSyncRequestToLocus --> ".concat(_this14.debugId, " Sync request succeeded for \"").concat(dataSet.name, "\""));
|
|
1685
2024
|
if (!resp.body || (0, _lodash.isEmpty)(resp.body)) {
|
|
1686
|
-
_loggerProxy.default.logger.info("HashTreeParser#sendSyncRequestToLocus --> ".concat(
|
|
2025
|
+
_loggerProxy.default.logger.info("HashTreeParser#sendSyncRequestToLocus --> ".concat(_this13.debugId, " Got ").concat(resp.statusCode, " with empty body for sync request for data set \"").concat(dataSet.name, "\", data should arrive via messages"));
|
|
1687
2026
|
return null;
|
|
1688
2027
|
}
|
|
1689
2028
|
return resp.body;
|
|
1690
2029
|
}).catch(function (error) {
|
|
1691
|
-
_loggerProxy.default.logger.error("HashTreeParser#sendSyncRequestToLocus --> ".concat(
|
|
1692
|
-
|
|
2030
|
+
_loggerProxy.default.logger.error("HashTreeParser#sendSyncRequestToLocus --> ".concat(_this13.debugId, " Error ").concat(error.statusCode, " sending sync request for data set \"").concat(dataSet.name, "\":"), error);
|
|
2031
|
+
_this13.checkForSentinelHttpResponse(error, dataSet.name);
|
|
2032
|
+
_metrics.default.sendBehavioralMetric(_constants.default.HASH_TREE_SYNC_FAILURE, {
|
|
2033
|
+
debugId: _this13.debugId,
|
|
2034
|
+
dataSetName: dataSet.name,
|
|
2035
|
+
request: 'POST /sync',
|
|
2036
|
+
statusCode: error.statusCode,
|
|
2037
|
+
reason: error.message
|
|
2038
|
+
});
|
|
1693
2039
|
throw error;
|
|
1694
2040
|
});
|
|
1695
2041
|
}
|