@webex/plugin-meetings 3.12.0-mobius-socket.1 → 3.12.0-mobius-socket.3
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 +3 -2
- package/dist/breakouts/index.js.map +1 -1
- package/dist/config.js +1 -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 +651 -382
- 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/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 +848 -582
- 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 +205 -77
- 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 +67 -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/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 +1 -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 +83 -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 +65 -1
- package/dist/types/meeting/util.d.ts +8 -0
- package/dist/types/meetings/index.d.ts +20 -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/reactions/reactions.type.d.ts +3 -0
- package/dist/webinar/index.js +68 -17
- 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 +1 -0
- package/src/config.ts +1 -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 +375 -197
- 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/properties.ts +1 -0
- package/src/meeting/in-meeting-actions.ts +4 -0
- package/src/meeting/index.ts +260 -23
- package/src/meeting/util.ts +20 -2
- package/src/meetings/index.ts +109 -43
- package/src/meetings/meetings.types.ts +19 -0
- package/src/meetings/request.ts +43 -0
- package/src/meetings/util.ts +80 -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/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 +88 -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 +2 -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 +1263 -157
- 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/meeting/in-meeting-actions.ts +2 -0
- package/test/unit/spec/meeting/index.js +902 -14
- 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 +309 -10
- package/test/unit/spec/meetings/request.js +141 -0
- package/test/unit/spec/meetings/utils.js +161 -0
- package/test/unit/spec/member/index.js +7 -0
- package/test/unit/spec/member/util.js +24 -0
- package/test/unit/spec/recording-controller/index.js +9 -8
- package/test/unit/spec/webinar/index.ts +81 -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,26 +608,39 @@ 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
|
-
_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
|
-
var name = _ref2.name,
|
|
622
|
-
root = _ref2.root,
|
|
623
|
-
leafCount = _ref2.leafCount,
|
|
624
|
-
version = _ref2.version;
|
|
625
|
-
return {
|
|
626
|
-
name: name,
|
|
627
|
-
root: root,
|
|
628
|
-
leafCount: leafCount,
|
|
629
|
-
version: version
|
|
630
|
-
};
|
|
631
|
-
}))));
|
|
632
613
|
dataSets.forEach(function (dataSet) {
|
|
633
|
-
|
|
634
|
-
|
|
614
|
+
_this4.updateDataSetInfo(dataSet);
|
|
615
|
+
_this4.runSyncAlgorithm(dataSet);
|
|
635
616
|
});
|
|
636
617
|
}
|
|
637
618
|
|
|
619
|
+
/**
|
|
620
|
+
* Handles known errors that can happen during syncs
|
|
621
|
+
*
|
|
622
|
+
* @param {any} error - The error to handle
|
|
623
|
+
* @returns {boolean} true if the error was recognized and handled, false otherwise
|
|
624
|
+
*/
|
|
625
|
+
}, {
|
|
626
|
+
key: "handleSyncErrors",
|
|
627
|
+
value: function handleSyncErrors(error) {
|
|
628
|
+
if (error instanceof MeetingEndedError) {
|
|
629
|
+
this.callLocusInfoUpdateCallback({
|
|
630
|
+
updateType: LocusInfoUpdateType.MEETING_ENDED
|
|
631
|
+
});
|
|
632
|
+
return true;
|
|
633
|
+
}
|
|
634
|
+
if (error instanceof LocusNotFoundError) {
|
|
635
|
+
this.callLocusInfoUpdateCallback({
|
|
636
|
+
updateType: LocusInfoUpdateType.LOCUS_NOT_FOUND
|
|
637
|
+
});
|
|
638
|
+
this.stop();
|
|
639
|
+
return true;
|
|
640
|
+
}
|
|
641
|
+
return false;
|
|
642
|
+
}
|
|
643
|
+
|
|
638
644
|
/**
|
|
639
645
|
* Asynchronously initializes new visible data sets
|
|
640
646
|
*
|
|
@@ -644,18 +650,14 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
644
650
|
}, {
|
|
645
651
|
key: "queueInitForNewVisibleDataSets",
|
|
646
652
|
value: function queueInitForNewVisibleDataSets(dataSetsRequiringInitialization) {
|
|
647
|
-
var
|
|
653
|
+
var _this5 = this;
|
|
648
654
|
_loggerProxy.default.logger.info("HashTreeParser#queueInitForNewVisibleDataSets --> ".concat(this.debugId, " queuing initialization of new visible datasets: ").concat(dataSetsRequiringInitialization.map(function (ds) {
|
|
649
655
|
return ds.name;
|
|
650
656
|
}).join(', ')));
|
|
651
657
|
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) {
|
|
658
|
+
_this5.initializeNewVisibleDataSets(dataSetsRequiringInitialization).catch(function (error) {
|
|
659
|
+
if (!_this5.handleSyncErrors(error)) {
|
|
660
|
+
_loggerProxy.default.logger.warn("HashTreeParser#queueInitForNewVisibleDataSets --> ".concat(_this5.debugId, " error while initializing new visible datasets: ").concat(dataSetsRequiringInitialization.map(function (ds) {
|
|
659
661
|
return ds.name;
|
|
660
662
|
}).join(', '), ": "), error);
|
|
661
663
|
}
|
|
@@ -715,14 +717,18 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
715
717
|
}, {
|
|
716
718
|
key: "handleLocusUpdate",
|
|
717
719
|
value: function handleLocusUpdate(update) {
|
|
718
|
-
var
|
|
720
|
+
var _this6 = this;
|
|
719
721
|
if (this.state === 'stopped') {
|
|
720
722
|
return;
|
|
721
723
|
}
|
|
722
724
|
var dataSets = update.dataSets,
|
|
723
725
|
locus = update.locus,
|
|
724
726
|
metadata = update.metadata;
|
|
727
|
+
_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) {
|
|
728
|
+
return ds.name;
|
|
729
|
+
}).join(','), " metadata=").concat(metadata ? 'yes' : 'no'));
|
|
725
730
|
if (!dataSets) {
|
|
731
|
+
// this happens for example when we handle GET /loci response
|
|
726
732
|
_loggerProxy.default.logger.info("HashTreeParser#handleLocusUpdate --> ".concat(this.debugId, " received hash tree update without dataSets"));
|
|
727
733
|
} else {
|
|
728
734
|
var _iterator5 = _createForOfIteratorHelper(dataSets),
|
|
@@ -752,19 +758,19 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
752
758
|
|
|
753
759
|
// then process the data in hash trees, if it is a new version, then add it to updatedObjects
|
|
754
760
|
(0, _keys.default)(leafInfo).forEach(function (dataSetName) {
|
|
755
|
-
if (
|
|
756
|
-
if (
|
|
757
|
-
var appliedChangesList =
|
|
761
|
+
if (_this6.dataSets[dataSetName]) {
|
|
762
|
+
if (_this6.dataSets[dataSetName].hashTree) {
|
|
763
|
+
var appliedChangesList = _this6.dataSets[dataSetName].hashTree.putItems(leafInfo[dataSetName].map(function (leaf) {
|
|
758
764
|
return {
|
|
759
765
|
id: leaf.id,
|
|
760
766
|
type: leaf.type,
|
|
761
767
|
version: leaf.version
|
|
762
768
|
};
|
|
763
769
|
}));
|
|
764
|
-
(0, _lodash.zip)(appliedChangesList, leafInfo[dataSetName]).forEach(function (
|
|
765
|
-
var
|
|
766
|
-
changeApplied =
|
|
767
|
-
leaf =
|
|
770
|
+
(0, _lodash.zip)(appliedChangesList, leafInfo[dataSetName]).forEach(function (_ref2) {
|
|
771
|
+
var _ref3 = (0, _slicedToArray2.default)(_ref2, 2),
|
|
772
|
+
changeApplied = _ref3[0],
|
|
773
|
+
leaf = _ref3[1];
|
|
768
774
|
if (changeApplied) {
|
|
769
775
|
updatedObjects.push({
|
|
770
776
|
htMeta: {
|
|
@@ -781,10 +787,10 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
781
787
|
});
|
|
782
788
|
} else {
|
|
783
789
|
// no hash tree means that the data set is not visible
|
|
784
|
-
_loggerProxy.default.logger.warn("HashTreeParser#handleLocusUpdate --> ".concat(
|
|
790
|
+
_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
791
|
}
|
|
786
792
|
} else {
|
|
787
|
-
_loggerProxy.default.logger.info("HashTreeParser#handleLocusUpdate --> ".concat(
|
|
793
|
+
_loggerProxy.default.logger.info("HashTreeParser#handleLocusUpdate --> ".concat(_this6.debugId, " received leaf data for unknown data set \"").concat(dataSetName, "\", ignoring"));
|
|
788
794
|
}
|
|
789
795
|
});
|
|
790
796
|
if (updatedObjects.length === 0) {
|
|
@@ -824,6 +830,21 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
824
830
|
}
|
|
825
831
|
}
|
|
826
832
|
|
|
833
|
+
/**
|
|
834
|
+
* Updates the leaf count for a data set, resizing its hash tree accordingly.
|
|
835
|
+
*
|
|
836
|
+
* @param {InternalDataSet} dataSet - The data set to update
|
|
837
|
+
* @param {number} newLeafCount - The new leaf count
|
|
838
|
+
* @returns {void}
|
|
839
|
+
*/
|
|
840
|
+
}, {
|
|
841
|
+
key: "updateDataSetLeafCount",
|
|
842
|
+
value: function updateDataSetLeafCount(dataSet, newLeafCount) {
|
|
843
|
+
var _dataSet$hashTree;
|
|
844
|
+
(_dataSet$hashTree = dataSet.hashTree) === null || _dataSet$hashTree === void 0 ? void 0 : _dataSet$hashTree.resize(newLeafCount);
|
|
845
|
+
dataSet.leafCount = newLeafCount;
|
|
846
|
+
}
|
|
847
|
+
|
|
827
848
|
/**
|
|
828
849
|
* Checks for changes in the visible data sets based on the updated objects.
|
|
829
850
|
* @param {HashTreeObject[]} updatedObjects - The list of updated hash tree objects.
|
|
@@ -832,7 +853,7 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
832
853
|
}, {
|
|
833
854
|
key: "checkForVisibleDataSetChanges",
|
|
834
855
|
value: function checkForVisibleDataSetChanges(updatedObjects) {
|
|
835
|
-
var
|
|
856
|
+
var _this7 = this;
|
|
836
857
|
var removedDataSets = [];
|
|
837
858
|
var addedDataSets = [];
|
|
838
859
|
|
|
@@ -841,20 +862,20 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
841
862
|
var _object$data;
|
|
842
863
|
if ((0, _utils.isMetadata)(object) && (_object$data = object.data) !== null && _object$data !== void 0 && _object$data.visibleDataSets) {
|
|
843
864
|
var newVisibleDataSets = object.data.visibleDataSets.filter(function (vds) {
|
|
844
|
-
return !
|
|
865
|
+
return !_this7.isExcludedDataSet(vds.name);
|
|
845
866
|
});
|
|
846
|
-
removedDataSets =
|
|
867
|
+
removedDataSets = _this7.visibleDataSets.filter(function (ds) {
|
|
847
868
|
return !newVisibleDataSets.some(function (nvs) {
|
|
848
869
|
return nvs.name === ds.name;
|
|
849
870
|
});
|
|
850
871
|
});
|
|
851
872
|
addedDataSets = newVisibleDataSets.filter(function (nvs) {
|
|
852
|
-
return
|
|
873
|
+
return _this7.visibleDataSets.every(function (ds) {
|
|
853
874
|
return ds.name !== nvs.name;
|
|
854
875
|
});
|
|
855
876
|
});
|
|
856
877
|
if (removedDataSets.length > 0 || addedDataSets.length > 0) {
|
|
857
|
-
_loggerProxy.default.logger.info("HashTreeParser#checkForVisibleDataSetChanges --> ".concat(
|
|
878
|
+
_loggerProxy.default.logger.info("HashTreeParser#checkForVisibleDataSetChanges --> ".concat(_this7.debugId, " visible data sets change: removed: ").concat(removedDataSets.map(function (ds) {
|
|
858
879
|
return ds.name;
|
|
859
880
|
}).join(', '), ", added: ").concat(addedDataSets.map(function (ds) {
|
|
860
881
|
return ds.name;
|
|
@@ -908,16 +929,16 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
908
929
|
}, {
|
|
909
930
|
key: "processVisibleDataSetChanges",
|
|
910
931
|
value: function processVisibleDataSetChanges(removedDataSets, addedDataSets, updatedObjects) {
|
|
911
|
-
var
|
|
932
|
+
var _this8 = this;
|
|
912
933
|
var dataSetsRequiringInitialization = [];
|
|
913
934
|
|
|
914
935
|
// if a visible data set was removed, we need to tell our client that all objects from it are removed
|
|
915
936
|
var removedObjects = [];
|
|
916
937
|
removedDataSets.forEach(function (ds) {
|
|
917
|
-
var
|
|
918
|
-
if ((
|
|
919
|
-
for (var i = 0; i <
|
|
920
|
-
removedObjects.push.apply(removedObjects, (0, _toConsumableArray2.default)(
|
|
938
|
+
var _this8$dataSets$ds$na;
|
|
939
|
+
if ((_this8$dataSets$ds$na = _this8.dataSets[ds.name]) !== null && _this8$dataSets$ds$na !== void 0 && _this8$dataSets$ds$na.hashTree) {
|
|
940
|
+
for (var i = 0; i < _this8.dataSets[ds.name].hashTree.numLeaves; i += 1) {
|
|
941
|
+
removedObjects.push.apply(removedObjects, (0, _toConsumableArray2.default)(_this8.dataSets[ds.name].hashTree.getLeafData(i).map(function (elementId) {
|
|
921
942
|
return {
|
|
922
943
|
htMeta: {
|
|
923
944
|
elementId: elementId,
|
|
@@ -927,7 +948,7 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
927
948
|
};
|
|
928
949
|
})));
|
|
929
950
|
}
|
|
930
|
-
|
|
951
|
+
_this8.deleteHashTree(ds.name);
|
|
931
952
|
}
|
|
932
953
|
});
|
|
933
954
|
this.visibleDataSets = this.visibleDataSets.filter(function (vds) {
|
|
@@ -988,81 +1009,78 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
988
1009
|
}, {
|
|
989
1010
|
key: "initializeNewVisibleDataSets",
|
|
990
1011
|
value: (function () {
|
|
991
|
-
var _initializeNewVisibleDataSets = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function
|
|
992
|
-
var
|
|
1012
|
+
var _initializeNewVisibleDataSets = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee5(addedDataSets) {
|
|
1013
|
+
var _this9 = this;
|
|
993
1014
|
var allDataSets, _iterator7, _step7, _loop, _t2;
|
|
994
|
-
return _regenerator.default.wrap(function (
|
|
995
|
-
while (1) switch (
|
|
1015
|
+
return _regenerator.default.wrap(function (_context6) {
|
|
1016
|
+
while (1) switch (_context6.prev = _context6.next) {
|
|
996
1017
|
case 0:
|
|
997
1018
|
if (!(this.state === 'stopped')) {
|
|
998
|
-
|
|
1019
|
+
_context6.next = 1;
|
|
999
1020
|
break;
|
|
1000
1021
|
}
|
|
1001
|
-
return
|
|
1022
|
+
return _context6.abrupt("return");
|
|
1002
1023
|
case 1:
|
|
1003
|
-
|
|
1024
|
+
_context6.next = 2;
|
|
1004
1025
|
return this.getAllVisibleDataSetsFromLocus();
|
|
1005
1026
|
case 2:
|
|
1006
|
-
allDataSets =
|
|
1007
|
-
_iterator7 = _createForOfIteratorHelper(addedDataSets);
|
|
1008
|
-
|
|
1027
|
+
allDataSets = _context6.sent;
|
|
1028
|
+
_iterator7 = _createForOfIteratorHelper((0, _utils.sortByInitPriority)(addedDataSets, _constants3.DATA_SET_INIT_PRIORITY));
|
|
1029
|
+
_context6.prev = 3;
|
|
1009
1030
|
_loop = /*#__PURE__*/_regenerator.default.mark(function _loop() {
|
|
1010
|
-
var ds, dataSetInfo
|
|
1011
|
-
return _regenerator.default.wrap(function (
|
|
1012
|
-
while (1) switch (
|
|
1031
|
+
var ds, dataSetInfo;
|
|
1032
|
+
return _regenerator.default.wrap(function (_context5) {
|
|
1033
|
+
while (1) switch (_context5.prev = _context5.next) {
|
|
1013
1034
|
case 0:
|
|
1014
1035
|
ds = _step7.value;
|
|
1015
1036
|
dataSetInfo = allDataSets.find(function (d) {
|
|
1016
1037
|
return d.name === ds.name;
|
|
1017
1038
|
});
|
|
1018
|
-
_loggerProxy.default.logger.info("HashTreeParser#initializeNewVisibleDataSets --> ".concat(
|
|
1039
|
+
_loggerProxy.default.logger.info("HashTreeParser#initializeNewVisibleDataSets --> ".concat(_this9.debugId, " initializing data set \"").concat(ds.name, "\""));
|
|
1019
1040
|
if (dataSetInfo) {
|
|
1020
|
-
|
|
1041
|
+
_context5.next = 1;
|
|
1021
1042
|
break;
|
|
1022
1043
|
}
|
|
1023
|
-
_loggerProxy.default.logger.warn("HashTreeParser#initializeNewVisibleDataSets --> ".concat(
|
|
1024
|
-
|
|
1044
|
+
_loggerProxy.default.logger.warn("HashTreeParser#initializeNewVisibleDataSets --> ".concat(_this9.debugId, " missing info about data set \"").concat(ds.name, "\" in Locus response from visibleDataSetsUrl"));
|
|
1045
|
+
_context5.next = 2;
|
|
1025
1046
|
break;
|
|
1026
1047
|
case 1:
|
|
1027
|
-
|
|
1028
|
-
return
|
|
1048
|
+
_context5.next = 2;
|
|
1049
|
+
return _this9.initializeNewVisibleDataSet(ds, dataSetInfo);
|
|
1029
1050
|
case 2:
|
|
1030
|
-
updates = _context4.sent;
|
|
1031
|
-
_this0.callLocusInfoUpdateCallback(updates);
|
|
1032
|
-
case 3:
|
|
1033
1051
|
case "end":
|
|
1034
|
-
return
|
|
1052
|
+
return _context5.stop();
|
|
1035
1053
|
}
|
|
1036
1054
|
}, _loop);
|
|
1037
1055
|
});
|
|
1038
1056
|
_iterator7.s();
|
|
1039
1057
|
case 4:
|
|
1040
1058
|
if ((_step7 = _iterator7.n()).done) {
|
|
1041
|
-
|
|
1059
|
+
_context6.next = 6;
|
|
1042
1060
|
break;
|
|
1043
1061
|
}
|
|
1044
|
-
return
|
|
1062
|
+
return _context6.delegateYield(_loop(), "t0", 5);
|
|
1045
1063
|
case 5:
|
|
1046
|
-
|
|
1064
|
+
_context6.next = 4;
|
|
1047
1065
|
break;
|
|
1048
1066
|
case 6:
|
|
1049
|
-
|
|
1067
|
+
_context6.next = 8;
|
|
1050
1068
|
break;
|
|
1051
1069
|
case 7:
|
|
1052
|
-
|
|
1053
|
-
_t2 =
|
|
1070
|
+
_context6.prev = 7;
|
|
1071
|
+
_t2 = _context6["catch"](3);
|
|
1054
1072
|
_iterator7.e(_t2);
|
|
1055
1073
|
case 8:
|
|
1056
|
-
|
|
1074
|
+
_context6.prev = 8;
|
|
1057
1075
|
_iterator7.f();
|
|
1058
|
-
return
|
|
1076
|
+
return _context6.finish(8);
|
|
1059
1077
|
case 9:
|
|
1060
1078
|
case "end":
|
|
1061
|
-
return
|
|
1079
|
+
return _context6.stop();
|
|
1062
1080
|
}
|
|
1063
|
-
},
|
|
1081
|
+
}, _callee5, this, [[3, 7, 8, 9]]);
|
|
1064
1082
|
}));
|
|
1065
|
-
function initializeNewVisibleDataSets(
|
|
1083
|
+
function initializeNewVisibleDataSets(_x7) {
|
|
1066
1084
|
return _initializeNewVisibleDataSets.apply(this, arguments);
|
|
1067
1085
|
}
|
|
1068
1086
|
return initializeNewVisibleDataSets;
|
|
@@ -1078,24 +1096,33 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1078
1096
|
}, {
|
|
1079
1097
|
key: "parseMessage",
|
|
1080
1098
|
value: function parseMessage(message, debugText) {
|
|
1081
|
-
var _message$
|
|
1082
|
-
|
|
1083
|
-
_message$locusStateEl2
|
|
1099
|
+
var _message$dataSets,
|
|
1100
|
+
_message$locusStateEl,
|
|
1101
|
+
_message$locusStateEl2,
|
|
1102
|
+
_this0 = this;
|
|
1084
1103
|
if (this.state === 'stopped') {
|
|
1085
1104
|
return [];
|
|
1086
1105
|
}
|
|
1087
1106
|
var dataSets = message.dataSets,
|
|
1088
1107
|
visibleDataSetsUrl = message.visibleDataSetsUrl;
|
|
1089
|
-
_loggerProxy.default.logger.info("HashTreeParser#parseMessage --> ".concat(this.debugId, "
|
|
1090
|
-
|
|
1108
|
+
_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 (_ref4) {
|
|
1109
|
+
var name = _ref4.name,
|
|
1110
|
+
version = _ref4.version;
|
|
1111
|
+
return "".concat(name, ":").concat(version);
|
|
1112
|
+
}).join(','), ", elements: ").concat((_message$locusStateEl = message.locusStateElements) === null || _message$locusStateEl === void 0 ? void 0 : _message$locusStateEl.map(function (el) {
|
|
1113
|
+
return "".concat(el.htMeta.elementId.type, ":").concat(el.htMeta.elementId.id, ":").concat(el.htMeta.elementId.version).concat(el.data ? '+' : '-');
|
|
1114
|
+
}).join(',')));
|
|
1115
|
+
if (((_message$locusStateEl2 = message.locusStateElements) === null || _message$locusStateEl2 === void 0 ? void 0 : _message$locusStateEl2.length) === 0) {
|
|
1091
1116
|
_loggerProxy.default.logger.warn("HashTreeParser#parseMessage --> ".concat(this.debugId, " got empty locusStateElements!!!"));
|
|
1092
|
-
|
|
1117
|
+
_metrics.default.sendBehavioralMetric(_constants.default.HASH_TREE_EMPTY_LOCUS_STATE_ELEMENTS, {
|
|
1118
|
+
debugId: this.debugId
|
|
1119
|
+
});
|
|
1093
1120
|
}
|
|
1094
1121
|
|
|
1095
1122
|
// first, update our metadata about the datasets with info from the message
|
|
1096
1123
|
this.visibleDataSetsUrl = visibleDataSetsUrl;
|
|
1097
1124
|
dataSets.forEach(function (dataSet) {
|
|
1098
|
-
return
|
|
1125
|
+
return _this0.updateDataSetInfo(dataSet);
|
|
1099
1126
|
});
|
|
1100
1127
|
var updatedObjects = [];
|
|
1101
1128
|
|
|
@@ -1115,9 +1142,9 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1115
1142
|
_step8;
|
|
1116
1143
|
try {
|
|
1117
1144
|
for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
|
|
1118
|
-
var
|
|
1145
|
+
var _this0$dataSets$dataS;
|
|
1119
1146
|
var dataSetName = _step8.value;
|
|
1120
|
-
var hashTree = (
|
|
1147
|
+
var hashTree = (_this0$dataSets$dataS = _this0.dataSets[dataSetName]) === null || _this0$dataSets$dataS === void 0 ? void 0 : _this0$dataSets$dataS.hashTree;
|
|
1121
1148
|
if (hashTree && object.data) {
|
|
1122
1149
|
if (hashTree.putItem(object.htMeta.elementId)) {
|
|
1123
1150
|
updatedMetadataObjects.push(object);
|
|
@@ -1139,13 +1166,13 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1139
1166
|
dataSetsRequiringInitialization = this.processVisibleDataSetChanges(removedDataSets, addedDataSets, updatedObjects);
|
|
1140
1167
|
}
|
|
1141
1168
|
}
|
|
1142
|
-
if (
|
|
1169
|
+
if (message.locusStateElements && message.locusStateElements.length > 0) {
|
|
1143
1170
|
// by this point we now have this.dataSets setup for data sets from this message
|
|
1144
1171
|
// and hash trees created for the new visible data sets,
|
|
1145
1172
|
// so we can now process all the updates from the message
|
|
1146
1173
|
dataSets.forEach(function (dataSet) {
|
|
1147
|
-
if (
|
|
1148
|
-
var hashTree =
|
|
1174
|
+
if (_this0.dataSets[dataSet.name]) {
|
|
1175
|
+
var hashTree = _this0.dataSets[dataSet.name].hashTree;
|
|
1149
1176
|
if (hashTree) {
|
|
1150
1177
|
var locusStateElementsForThisSet = message.locusStateElements.filter(function (object) {
|
|
1151
1178
|
return object.htMeta.dataSetNames.includes(dataSet.name);
|
|
@@ -1169,10 +1196,10 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1169
1196
|
}
|
|
1170
1197
|
});
|
|
1171
1198
|
} else {
|
|
1172
|
-
_loggerProxy.default.logger.info("Locus-info:index#parseMessage --> ".concat(
|
|
1199
|
+
_loggerProxy.default.logger.info("Locus-info:index#parseMessage --> ".concat(_this0.debugId, " unexpected (not visible) dataSet ").concat(dataSet.name, " received in hash tree message"));
|
|
1173
1200
|
}
|
|
1174
1201
|
}
|
|
1175
|
-
|
|
1202
|
+
_this0.runSyncAlgorithm(dataSet);
|
|
1176
1203
|
});
|
|
1177
1204
|
}
|
|
1178
1205
|
if (dataSetsRequiringInitialization.length > 0) {
|
|
@@ -1229,25 +1256,25 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1229
1256
|
}, {
|
|
1230
1257
|
key: "callLocusInfoUpdateCallback",
|
|
1231
1258
|
value: function callLocusInfoUpdateCallback(updates) {
|
|
1232
|
-
var
|
|
1259
|
+
var _updates$updatedObjec,
|
|
1260
|
+
_this1 = this;
|
|
1233
1261
|
if (this.state === 'stopped') {
|
|
1234
1262
|
return;
|
|
1235
1263
|
}
|
|
1236
|
-
var updateType = updates.updateType
|
|
1237
|
-
|
|
1238
|
-
if (updateType === LocusInfoUpdateType.OBJECTS_UPDATED && (updatedObjects === null || updatedObjects === void 0 ? void 0 : updatedObjects.length) > 0) {
|
|
1264
|
+
var updateType = updates.updateType;
|
|
1265
|
+
if (updateType === LocusInfoUpdateType.OBJECTS_UPDATED && ((_updates$updatedObjec = updates.updatedObjects) === null || _updates$updatedObjec === void 0 ? void 0 : _updates$updatedObjec.length) > 0) {
|
|
1239
1266
|
// Filter out updates for objects that already have a higher version in their datasets,
|
|
1240
1267
|
// or removals for objects that still exist in any of their datasets
|
|
1241
|
-
var filteredUpdates = updatedObjects.filter(function (object) {
|
|
1268
|
+
var filteredUpdates = updates.updatedObjects.filter(function (object) {
|
|
1242
1269
|
var elementId = object.htMeta.elementId;
|
|
1243
1270
|
var type = elementId.type,
|
|
1244
1271
|
id = elementId.id,
|
|
1245
1272
|
version = elementId.version;
|
|
1246
1273
|
|
|
1247
1274
|
// Check all datasets
|
|
1248
|
-
for (var _i2 = 0, _Object$keys3 = (0, _keys.default)(
|
|
1275
|
+
for (var _i2 = 0, _Object$keys3 = (0, _keys.default)(_this1.dataSets); _i2 < _Object$keys3.length; _i2++) {
|
|
1249
1276
|
var dataSetName = _Object$keys3[_i2];
|
|
1250
|
-
var dataSet =
|
|
1277
|
+
var dataSet = _this1.dataSets[dataSetName];
|
|
1251
1278
|
|
|
1252
1279
|
// only visible datasets have hash trees set
|
|
1253
1280
|
if (dataSet !== null && dataSet !== void 0 && dataSet.hashTree) {
|
|
@@ -1256,12 +1283,12 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1256
1283
|
if (object.data) {
|
|
1257
1284
|
// For updates: filter out if any dataset has a higher version
|
|
1258
1285
|
if (existingVersion > version) {
|
|
1259
|
-
_loggerProxy.default.logger.info("HashTreeParser#callLocusInfoUpdateCallback --> ".concat(
|
|
1286
|
+
_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
1287
|
return false;
|
|
1261
1288
|
}
|
|
1262
1289
|
} else if (existingVersion >= version) {
|
|
1263
1290
|
// For removals: filter out if the object still exists in any dataset
|
|
1264
|
-
_loggerProxy.default.logger.info("HashTreeParser#callLocusInfoUpdateCallback --> ".concat(
|
|
1291
|
+
_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
1292
|
return false;
|
|
1266
1293
|
}
|
|
1267
1294
|
}
|
|
@@ -1270,13 +1297,14 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1270
1297
|
return true;
|
|
1271
1298
|
});
|
|
1272
1299
|
if (filteredUpdates.length > 0) {
|
|
1273
|
-
this.locusInfoUpdateCallback(
|
|
1300
|
+
this.locusInfoUpdateCallback({
|
|
1301
|
+
updateType: updateType,
|
|
1274
1302
|
updatedObjects: filteredUpdates
|
|
1275
1303
|
});
|
|
1276
1304
|
}
|
|
1277
1305
|
} else if (updateType !== LocusInfoUpdateType.OBJECTS_UPDATED) {
|
|
1278
|
-
this.locusInfoUpdateCallback(
|
|
1279
|
-
|
|
1306
|
+
this.locusInfoUpdateCallback({
|
|
1307
|
+
updateType: updateType
|
|
1280
1308
|
});
|
|
1281
1309
|
}
|
|
1282
1310
|
}
|
|
@@ -1300,102 +1328,289 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1300
1328
|
* Performs a sync for the given data set.
|
|
1301
1329
|
*
|
|
1302
1330
|
* @param {InternalDataSet} dataSet - The data set to sync
|
|
1303
|
-
* @param {string} rootHash - Our current root hash for this data set
|
|
1304
1331
|
* @param {string} reason - The reason for the sync (used for logging)
|
|
1332
|
+
* @param {boolean} [isInitialization] - Whether this is an initialization sync (sends empty leaves data instead of comparing hashes)
|
|
1305
1333
|
* @returns {Promise<void>}
|
|
1306
1334
|
*/
|
|
1307
1335
|
}, {
|
|
1308
1336
|
key: "performSync",
|
|
1309
1337
|
value: (function () {
|
|
1310
|
-
var _performSync = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function
|
|
1311
|
-
var
|
|
1312
|
-
return _regenerator.default.wrap(function (
|
|
1313
|
-
while (1) switch (
|
|
1338
|
+
var _performSync = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee6(dataSet, reason, isInitialization) {
|
|
1339
|
+
var hashTree, rootHash, leavesData, receivedHashes, hashesResult, mismatchedLeaveIndexes, syncResponse, _t3, _t4;
|
|
1340
|
+
return _regenerator.default.wrap(function (_context7) {
|
|
1341
|
+
while (1) switch (_context7.prev = _context7.next) {
|
|
1314
1342
|
case 0:
|
|
1315
1343
|
if (dataSet.hashTree) {
|
|
1316
|
-
|
|
1344
|
+
_context7.next = 1;
|
|
1317
1345
|
break;
|
|
1318
1346
|
}
|
|
1319
|
-
return
|
|
1347
|
+
return _context7.abrupt("return");
|
|
1320
1348
|
case 1:
|
|
1321
|
-
|
|
1349
|
+
hashTree = dataSet.hashTree;
|
|
1350
|
+
rootHash = hashTree.getRootHash();
|
|
1351
|
+
_context7.prev = 2;
|
|
1322
1352
|
_loggerProxy.default.logger.info("HashTreeParser#performSync --> ".concat(this.debugId, " ").concat(reason, ", syncing data set \"").concat(dataSet.name, "\""));
|
|
1323
|
-
|
|
1353
|
+
leavesData = {};
|
|
1354
|
+
if (isInitialization) {
|
|
1355
|
+
_context7.next = 10;
|
|
1356
|
+
break;
|
|
1357
|
+
}
|
|
1324
1358
|
if (!(dataSet.leafCount !== 1)) {
|
|
1325
|
-
|
|
1359
|
+
_context7.next = 9;
|
|
1326
1360
|
break;
|
|
1327
1361
|
}
|
|
1328
|
-
|
|
1329
|
-
|
|
1362
|
+
_context7.prev = 3;
|
|
1363
|
+
_context7.next = 4;
|
|
1330
1364
|
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
1365
|
case 4:
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1366
|
+
hashesResult = _context7.sent;
|
|
1367
|
+
if (hashesResult) {
|
|
1368
|
+
_context7.next = 5;
|
|
1369
|
+
break;
|
|
1370
|
+
}
|
|
1371
|
+
return _context7.abrupt("return");
|
|
1372
|
+
case 5:
|
|
1373
|
+
receivedHashes = hashesResult.hashes;
|
|
1374
|
+
this.updateDataSetLeafCount(dataSet, hashesResult.dataSet.leafCount);
|
|
1375
|
+
_context7.next = 8;
|
|
1376
|
+
break;
|
|
1377
|
+
case 6:
|
|
1378
|
+
_context7.prev = 6;
|
|
1379
|
+
_t3 = _context7["catch"](3);
|
|
1380
|
+
if (!((_t3 === null || _t3 === void 0 ? void 0 : _t3.statusCode) === 409)) {
|
|
1381
|
+
_context7.next = 7;
|
|
1344
1382
|
break;
|
|
1345
1383
|
}
|
|
1346
1384
|
// this is a leaf count mismatch, we should do nothing, just wait for another heartbeat message from Locus
|
|
1347
1385
|
_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
|
|
1386
|
+
return _context7.abrupt("return");
|
|
1387
|
+
case 7:
|
|
1350
1388
|
throw _t3;
|
|
1351
|
-
case
|
|
1389
|
+
case 8:
|
|
1352
1390
|
// identify mismatched leaves
|
|
1353
|
-
mismatchedLeaveIndexes =
|
|
1391
|
+
mismatchedLeaveIndexes = hashTree.diffHashes(receivedHashes);
|
|
1354
1392
|
mismatchedLeaveIndexes.forEach(function (index) {
|
|
1355
|
-
|
|
1393
|
+
leavesData[index] = hashTree.getLeafData(index);
|
|
1356
1394
|
});
|
|
1357
|
-
|
|
1395
|
+
_context7.next = 10;
|
|
1358
1396
|
break;
|
|
1359
|
-
case
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1397
|
+
case 9:
|
|
1398
|
+
leavesData = {
|
|
1399
|
+
0: hashTree.getLeafData(0)
|
|
1400
|
+
};
|
|
1401
|
+
case 10:
|
|
1402
|
+
// request sync for mismatched leaves
|
|
1403
|
+
syncResponse = null;
|
|
1404
|
+
if (!isInitialization) {
|
|
1405
|
+
_context7.next = 12;
|
|
1364
1406
|
break;
|
|
1365
1407
|
}
|
|
1366
|
-
|
|
1367
|
-
return this.sendSyncRequestToLocus(dataSet,
|
|
1368
|
-
|
|
1369
|
-
|
|
1408
|
+
_context7.next = 11;
|
|
1409
|
+
return this.sendSyncRequestToLocus(dataSet, {
|
|
1410
|
+
isInitialization: true
|
|
1411
|
+
});
|
|
1412
|
+
case 11:
|
|
1413
|
+
syncResponse = _context7.sent;
|
|
1414
|
+
_context7.next = 14;
|
|
1415
|
+
break;
|
|
1416
|
+
case 12:
|
|
1417
|
+
if (!((0, _keys.default)(leavesData).length > 0)) {
|
|
1418
|
+
_context7.next = 14;
|
|
1419
|
+
break;
|
|
1420
|
+
}
|
|
1421
|
+
_context7.next = 13;
|
|
1422
|
+
return this.sendSyncRequestToLocus(dataSet, {
|
|
1423
|
+
mismatchedLeavesData: leavesData
|
|
1424
|
+
});
|
|
1425
|
+
case 13:
|
|
1426
|
+
syncResponse = _context7.sent;
|
|
1427
|
+
case 14:
|
|
1370
1428
|
// sync API may return nothing (in that case data will arrive via messages)
|
|
1371
1429
|
// or it may return a response in the same format as messages
|
|
1430
|
+
// We still need to restart the sync timer as a safety net in case the messages don't arrive.
|
|
1431
|
+
this.runSyncAlgorithm(dataSet);
|
|
1372
1432
|
if (syncResponse) {
|
|
1433
|
+
// the format of sync response is the same as messages, so we can reuse the same handler
|
|
1373
1434
|
this.handleMessage(syncResponse, 'via sync API');
|
|
1374
1435
|
}
|
|
1375
|
-
|
|
1376
|
-
_context6.next = 12;
|
|
1436
|
+
_context7.next = 16;
|
|
1377
1437
|
break;
|
|
1378
|
-
case
|
|
1379
|
-
|
|
1380
|
-
_t4 =
|
|
1381
|
-
if (_t4
|
|
1382
|
-
this.callLocusInfoUpdateCallback({
|
|
1383
|
-
updateType: LocusInfoUpdateType.MEETING_ENDED
|
|
1384
|
-
});
|
|
1385
|
-
} else {
|
|
1438
|
+
case 15:
|
|
1439
|
+
_context7.prev = 15;
|
|
1440
|
+
_t4 = _context7["catch"](2);
|
|
1441
|
+
if (!this.handleSyncErrors(_t4)) {
|
|
1386
1442
|
_loggerProxy.default.logger.warn("HashTreeParser#performSync --> ".concat(this.debugId, " error during sync for data set \"").concat(dataSet.name, "\":"), _t4);
|
|
1387
1443
|
}
|
|
1388
|
-
case
|
|
1444
|
+
case 16:
|
|
1389
1445
|
case "end":
|
|
1390
|
-
return
|
|
1446
|
+
return _context7.stop();
|
|
1391
1447
|
}
|
|
1392
|
-
},
|
|
1448
|
+
}, _callee6, this, [[2, 15], [3, 6]]);
|
|
1393
1449
|
}));
|
|
1394
|
-
function performSync(
|
|
1450
|
+
function performSync(_x8, _x9, _x0) {
|
|
1395
1451
|
return _performSync.apply(this, arguments);
|
|
1396
1452
|
}
|
|
1397
1453
|
return performSync;
|
|
1398
1454
|
}()
|
|
1455
|
+
/**
|
|
1456
|
+
* Enqueues a sync for the given data set. If the data set is already in the queue, the request is ignored.
|
|
1457
|
+
* This ensures that all syncs are executed sequentially and no more than 1 sync runs at a time.
|
|
1458
|
+
*
|
|
1459
|
+
* @param {string} dataSetName - The name of the data set to sync
|
|
1460
|
+
* @param {string} reason - The reason for the sync (used for logging)
|
|
1461
|
+
* @param {boolean} [isInitialization=false] - Whether this is an initialization sync (uses empty leaves data instead of hash comparison)
|
|
1462
|
+
* @returns {void}
|
|
1463
|
+
*/
|
|
1464
|
+
)
|
|
1465
|
+
}, {
|
|
1466
|
+
key: "enqueueSyncForDataset",
|
|
1467
|
+
value: function enqueueSyncForDataset(dataSetName, reason) {
|
|
1468
|
+
var isInitialization = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
1469
|
+
if (this.state === 'stopped') return;
|
|
1470
|
+
var existingEntry = this.syncQueue.find(function (entry) {
|
|
1471
|
+
return entry.dataSetName === dataSetName;
|
|
1472
|
+
});
|
|
1473
|
+
if (existingEntry) {
|
|
1474
|
+
if (isInitialization) {
|
|
1475
|
+
existingEntry.isInitialization = true;
|
|
1476
|
+
}
|
|
1477
|
+
_loggerProxy.default.logger.info("HashTreeParser#enqueueSyncForDataset --> ".concat(this.debugId, " data set \"").concat(dataSetName, "\" already in sync queue, skipping"));
|
|
1478
|
+
return;
|
|
1479
|
+
}
|
|
1480
|
+
this.syncQueue.push({
|
|
1481
|
+
dataSetName: dataSetName,
|
|
1482
|
+
reason: reason,
|
|
1483
|
+
isInitialization: isInitialization
|
|
1484
|
+
});
|
|
1485
|
+
if (!this.isSyncInProgress) {
|
|
1486
|
+
this.syncQueueProcessingPromise = this.processSyncQueue();
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1490
|
+
/**
|
|
1491
|
+
* Processes the sync queue sequentially. Only one instance of this method runs at a time.
|
|
1492
|
+
*
|
|
1493
|
+
* @returns {Promise<void>}
|
|
1494
|
+
*/
|
|
1495
|
+
}, {
|
|
1496
|
+
key: "processSyncQueue",
|
|
1497
|
+
value: (function () {
|
|
1498
|
+
var _processSyncQueue = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee7() {
|
|
1499
|
+
var _ref7, dataSetName, reason, isInitialization, dataSet;
|
|
1500
|
+
return _regenerator.default.wrap(function (_context8) {
|
|
1501
|
+
while (1) switch (_context8.prev = _context8.next) {
|
|
1502
|
+
case 0:
|
|
1503
|
+
if (!this.isSyncInProgress) {
|
|
1504
|
+
_context8.next = 1;
|
|
1505
|
+
break;
|
|
1506
|
+
}
|
|
1507
|
+
return _context8.abrupt("return");
|
|
1508
|
+
case 1:
|
|
1509
|
+
this.isSyncInProgress = true;
|
|
1510
|
+
_context8.prev = 2;
|
|
1511
|
+
case 3:
|
|
1512
|
+
if (!(this.syncQueue.length > 0 && this.state !== 'stopped')) {
|
|
1513
|
+
_context8.next = 6;
|
|
1514
|
+
break;
|
|
1515
|
+
}
|
|
1516
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
1517
|
+
_ref7 = this.syncQueue.shift(), dataSetName = _ref7.dataSetName, reason = _ref7.reason, isInitialization = _ref7.isInitialization;
|
|
1518
|
+
dataSet = this.dataSets[dataSetName];
|
|
1519
|
+
if (dataSet !== null && dataSet !== void 0 && dataSet.hashTree) {
|
|
1520
|
+
_context8.next = 4;
|
|
1521
|
+
break;
|
|
1522
|
+
}
|
|
1523
|
+
return _context8.abrupt("continue", 3);
|
|
1524
|
+
case 4:
|
|
1525
|
+
_context8.next = 5;
|
|
1526
|
+
return this.performSync(dataSet, reason, isInitialization);
|
|
1527
|
+
case 5:
|
|
1528
|
+
_context8.next = 3;
|
|
1529
|
+
break;
|
|
1530
|
+
case 6:
|
|
1531
|
+
_context8.prev = 6;
|
|
1532
|
+
this.isSyncInProgress = false;
|
|
1533
|
+
return _context8.finish(6);
|
|
1534
|
+
case 7:
|
|
1535
|
+
case "end":
|
|
1536
|
+
return _context8.stop();
|
|
1537
|
+
}
|
|
1538
|
+
}, _callee7, this, [[2,, 6, 7]]);
|
|
1539
|
+
}));
|
|
1540
|
+
function processSyncQueue() {
|
|
1541
|
+
return _processSyncQueue.apply(this, arguments);
|
|
1542
|
+
}
|
|
1543
|
+
return processSyncQueue;
|
|
1544
|
+
}()
|
|
1545
|
+
/**
|
|
1546
|
+
* Syncs all data sets that have hash trees, one by one in sequence, using the priority order
|
|
1547
|
+
* provided by sortByInitPriority(). Does nothing if the parser is stopped or if a syncAllDatasets
|
|
1548
|
+
* call is already in progress.
|
|
1549
|
+
*
|
|
1550
|
+
* @returns {Promise<void>}
|
|
1551
|
+
*/
|
|
1552
|
+
)
|
|
1553
|
+
}, {
|
|
1554
|
+
key: "syncAllDatasets",
|
|
1555
|
+
value: (function () {
|
|
1556
|
+
var _syncAllDatasets = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee8() {
|
|
1557
|
+
var dataSetsWithHashTrees, sorted, _iterator9, _step9, ds;
|
|
1558
|
+
return _regenerator.default.wrap(function (_context9) {
|
|
1559
|
+
while (1) switch (_context9.prev = _context9.next) {
|
|
1560
|
+
case 0:
|
|
1561
|
+
if (!(this.state === 'stopped')) {
|
|
1562
|
+
_context9.next = 1;
|
|
1563
|
+
break;
|
|
1564
|
+
}
|
|
1565
|
+
return _context9.abrupt("return");
|
|
1566
|
+
case 1:
|
|
1567
|
+
if (!this.isSyncAllInProgress) {
|
|
1568
|
+
_context9.next = 2;
|
|
1569
|
+
break;
|
|
1570
|
+
}
|
|
1571
|
+
return _context9.abrupt("return");
|
|
1572
|
+
case 2:
|
|
1573
|
+
this.isSyncAllInProgress = true;
|
|
1574
|
+
_context9.prev = 3;
|
|
1575
|
+
dataSetsWithHashTrees = (0, _values.default)(this.dataSets).filter(function (dataSet) {
|
|
1576
|
+
return dataSet === null || dataSet === void 0 ? void 0 : dataSet.hashTree;
|
|
1577
|
+
}).map(function (dataSet) {
|
|
1578
|
+
return {
|
|
1579
|
+
name: dataSet.name
|
|
1580
|
+
};
|
|
1581
|
+
});
|
|
1582
|
+
sorted = (0, _utils.sortByInitPriority)(dataSetsWithHashTrees, _constants3.DATA_SET_INIT_PRIORITY);
|
|
1583
|
+
_loggerProxy.default.logger.info("HashTreeParser#syncAllDatasets --> ".concat(this.debugId, " syncing datasets: ").concat(sorted.map(function (ds) {
|
|
1584
|
+
return ds.name;
|
|
1585
|
+
}).join(', ')));
|
|
1586
|
+
_iterator9 = _createForOfIteratorHelper(sorted);
|
|
1587
|
+
try {
|
|
1588
|
+
for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
|
|
1589
|
+
ds = _step9.value;
|
|
1590
|
+
this.enqueueSyncForDataset(ds.name, 'syncAllDatasets');
|
|
1591
|
+
}
|
|
1592
|
+
} catch (err) {
|
|
1593
|
+
_iterator9.e(err);
|
|
1594
|
+
} finally {
|
|
1595
|
+
_iterator9.f();
|
|
1596
|
+
}
|
|
1597
|
+
_context9.next = 4;
|
|
1598
|
+
return this.syncQueueProcessingPromise;
|
|
1599
|
+
case 4:
|
|
1600
|
+
_context9.prev = 4;
|
|
1601
|
+
this.isSyncAllInProgress = false;
|
|
1602
|
+
return _context9.finish(4);
|
|
1603
|
+
case 5:
|
|
1604
|
+
case "end":
|
|
1605
|
+
return _context9.stop();
|
|
1606
|
+
}
|
|
1607
|
+
}, _callee8, this, [[3,, 4, 5]]);
|
|
1608
|
+
}));
|
|
1609
|
+
function syncAllDatasets() {
|
|
1610
|
+
return _syncAllDatasets.apply(this, arguments);
|
|
1611
|
+
}
|
|
1612
|
+
return syncAllDatasets;
|
|
1613
|
+
}()
|
|
1399
1614
|
/**
|
|
1400
1615
|
* Runs the sync algorithm for the given data set.
|
|
1401
1616
|
*
|
|
@@ -1406,58 +1621,35 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1406
1621
|
}, {
|
|
1407
1622
|
key: "runSyncAlgorithm",
|
|
1408
1623
|
value: function runSyncAlgorithm(receivedDataSet) {
|
|
1409
|
-
var
|
|
1624
|
+
var _this10 = this;
|
|
1410
1625
|
var dataSet = this.dataSets[receivedDataSet.name];
|
|
1411
1626
|
if (!dataSet) {
|
|
1412
1627
|
_loggerProxy.default.logger.warn("HashTreeParser#runSyncAlgorithm --> ".concat(this.debugId, " No data set found for ").concat(receivedDataSet.name, ", skipping sync algorithm"));
|
|
1413
1628
|
return;
|
|
1414
1629
|
}
|
|
1415
1630
|
if (!dataSet.hashTree) {
|
|
1416
|
-
|
|
1631
|
+
// no hash tree, so no need to do any syncing
|
|
1632
|
+
// we fall into this branch often, because Locus sends dataSets in messages that are not visible to us
|
|
1633
|
+
|
|
1417
1634
|
return;
|
|
1418
1635
|
}
|
|
1419
1636
|
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
1637
|
var delay = dataSet.idleMs + this.getWeightedBackoffTime(dataSet.backoff);
|
|
1425
1638
|
if (delay > 0) {
|
|
1426
1639
|
if (dataSet.timer) {
|
|
1427
1640
|
clearTimeout(dataSet.timer);
|
|
1428
1641
|
}
|
|
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);
|
|
1642
|
+
dataSet.timer = setTimeout(function () {
|
|
1643
|
+
dataSet.timer = undefined;
|
|
1644
|
+
if (!dataSet.hashTree) {
|
|
1645
|
+
_loggerProxy.default.logger.warn("HashTreeParser#runSyncAlgorithm --> ".concat(_this10.debugId, " Data set \"").concat(dataSet.name, "\" no longer has a hash tree, cannot run sync algorithm"));
|
|
1646
|
+
return;
|
|
1647
|
+
}
|
|
1648
|
+
var rootHash = dataSet.hashTree.getRootHash();
|
|
1649
|
+
if (dataSet.root !== rootHash) {
|
|
1650
|
+
_this10.enqueueSyncForDataset(dataSet.name, "Root hash mismatch: received=".concat(dataSet.root, ", ours=").concat(rootHash));
|
|
1651
|
+
}
|
|
1652
|
+
}, delay);
|
|
1461
1653
|
} else {
|
|
1462
1654
|
_loggerProxy.default.logger.info("HashTreeParser#runSyncAlgorithm --> ".concat(this.debugId, " No delay for \"").concat(dataSet.name, "\" data set, skipping sync timer reset/setup"));
|
|
1463
1655
|
}
|
|
@@ -1475,16 +1667,16 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1475
1667
|
}, {
|
|
1476
1668
|
key: "resetHeartbeatWatchdogs",
|
|
1477
1669
|
value: function resetHeartbeatWatchdogs(receivedDataSets) {
|
|
1478
|
-
var
|
|
1670
|
+
var _this11 = this;
|
|
1479
1671
|
if (!this.heartbeatIntervalMs) {
|
|
1480
1672
|
return;
|
|
1481
1673
|
}
|
|
1482
|
-
var
|
|
1483
|
-
|
|
1674
|
+
var _iterator0 = _createForOfIteratorHelper(receivedDataSets),
|
|
1675
|
+
_step0;
|
|
1484
1676
|
try {
|
|
1485
1677
|
var _loop2 = function _loop2() {
|
|
1486
|
-
var receivedDataSet =
|
|
1487
|
-
var dataSet =
|
|
1678
|
+
var receivedDataSet = _step0.value;
|
|
1679
|
+
var dataSet = _this11.dataSets[receivedDataSet.name];
|
|
1488
1680
|
if (!(dataSet !== null && dataSet !== void 0 && dataSet.hashTree)) {
|
|
1489
1681
|
// eslint-disable-next-line no-continue
|
|
1490
1682
|
return 1; // continue
|
|
@@ -1493,30 +1685,26 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1493
1685
|
clearTimeout(dataSet.heartbeatWatchdogTimer);
|
|
1494
1686
|
dataSet.heartbeatWatchdogTimer = undefined;
|
|
1495
1687
|
}
|
|
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);
|
|
1688
|
+
var backoffTime = _this11.getWeightedBackoffTime(dataSet.backoff);
|
|
1689
|
+
var delay = _this11.heartbeatIntervalMs + backoffTime;
|
|
1690
|
+
dataSet.heartbeatWatchdogTimer = setTimeout(function () {
|
|
1691
|
+
dataSet.heartbeatWatchdogTimer = undefined;
|
|
1692
|
+
_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"));
|
|
1693
|
+
_metrics.default.sendBehavioralMetric(_constants.default.HASH_TREE_HEARTBEAT_WATCHDOG_EXPIRED, {
|
|
1694
|
+
debugId: _this11.debugId,
|
|
1695
|
+
dataSetName: dataSet.name
|
|
1696
|
+
});
|
|
1697
|
+
_this11.enqueueSyncForDataset(dataSet.name, "heartbeat watchdog expired");
|
|
1698
|
+
_this11.resetHeartbeatWatchdogs([dataSet]);
|
|
1699
|
+
}, delay);
|
|
1512
1700
|
};
|
|
1513
|
-
for (
|
|
1701
|
+
for (_iterator0.s(); !(_step0 = _iterator0.n()).done;) {
|
|
1514
1702
|
if (_loop2()) continue;
|
|
1515
1703
|
}
|
|
1516
1704
|
} catch (err) {
|
|
1517
|
-
|
|
1705
|
+
_iterator0.e(err);
|
|
1518
1706
|
} finally {
|
|
1519
|
-
|
|
1707
|
+
_iterator0.f();
|
|
1520
1708
|
}
|
|
1521
1709
|
}
|
|
1522
1710
|
|
|
@@ -1550,6 +1738,7 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1550
1738
|
value: function stop() {
|
|
1551
1739
|
_loggerProxy.default.logger.info("HashTreeParser#stop --> ".concat(this.debugId, " Stopping HashTreeParser, clearing timers and hash trees"));
|
|
1552
1740
|
this.stopAllTimers();
|
|
1741
|
+
this.syncQueue = [];
|
|
1553
1742
|
(0, _values.default)(this.dataSets).forEach(function (dataSet) {
|
|
1554
1743
|
dataSet.hashTree = undefined;
|
|
1555
1744
|
});
|
|
@@ -1558,29 +1747,41 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1558
1747
|
}
|
|
1559
1748
|
|
|
1560
1749
|
/**
|
|
1561
|
-
*
|
|
1750
|
+
* Cleans up the HashTreeParser, stopping all timers and clearing all internal state.
|
|
1751
|
+
* After calling this, the parser should not be used anymore.
|
|
1752
|
+
* @returns {void}
|
|
1753
|
+
*/
|
|
1754
|
+
}, {
|
|
1755
|
+
key: "cleanUp",
|
|
1756
|
+
value: function cleanUp() {
|
|
1757
|
+
this.stop();
|
|
1758
|
+
this.dataSets = {};
|
|
1759
|
+
}
|
|
1760
|
+
|
|
1761
|
+
/**
|
|
1762
|
+
* Resumes the HashTreeParser that was previously stopped, using a hash tree message.
|
|
1562
1763
|
* @param {HashTreeMessage} message - The message to resume with, it must contain metadata with visible data sets info
|
|
1563
1764
|
* @returns {void}
|
|
1564
1765
|
*/
|
|
1565
1766
|
}, {
|
|
1566
|
-
key: "
|
|
1567
|
-
value: function
|
|
1767
|
+
key: "resumeFromMessage",
|
|
1768
|
+
value: function resumeFromMessage(message) {
|
|
1568
1769
|
var _message$locusStateEl3, _metadataObject$data;
|
|
1569
1770
|
// check that message contains metadata with visible data sets - this is essential to be able to resume
|
|
1570
1771
|
var metadataObject = (_message$locusStateEl3 = message.locusStateElements) === null || _message$locusStateEl3 === void 0 ? void 0 : _message$locusStateEl3.find(function (el) {
|
|
1571
1772
|
return (0, _utils.isMetadata)(el);
|
|
1572
1773
|
});
|
|
1573
1774
|
if (!(metadataObject !== null && metadataObject !== void 0 && (_metadataObject$data = metadataObject.data) !== null && _metadataObject$data !== void 0 && _metadataObject$data.visibleDataSets)) {
|
|
1574
|
-
_loggerProxy.default.logger.warn("HashTreeParser#
|
|
1775
|
+
_loggerProxy.default.logger.warn("HashTreeParser#resumeFromMessage --> ".concat(this.debugId, " Cannot resume HashTreeParser because the message is missing metadata with visible data sets info"));
|
|
1575
1776
|
return;
|
|
1576
1777
|
}
|
|
1577
1778
|
this.setVisibleDataSets(metadataObject.data.visibleDataSets, message.dataSets);
|
|
1578
1779
|
this.dataSets = {};
|
|
1579
|
-
var
|
|
1580
|
-
|
|
1780
|
+
var _iterator1 = _createForOfIteratorHelper(message.dataSets),
|
|
1781
|
+
_step1;
|
|
1581
1782
|
try {
|
|
1582
|
-
for (
|
|
1583
|
-
var dataSet =
|
|
1783
|
+
for (_iterator1.s(); !(_step1 = _iterator1.n()).done;) {
|
|
1784
|
+
var dataSet = _step1.value;
|
|
1584
1785
|
var name = dataSet.name,
|
|
1585
1786
|
leafCount = dataSet.leafCount;
|
|
1586
1787
|
this.dataSets[name] = _objectSpread(_objectSpread({}, dataSet), {}, {
|
|
@@ -1588,23 +1789,62 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1588
1789
|
});
|
|
1589
1790
|
}
|
|
1590
1791
|
} catch (err) {
|
|
1591
|
-
|
|
1792
|
+
_iterator1.e(err);
|
|
1592
1793
|
} finally {
|
|
1593
|
-
|
|
1794
|
+
_iterator1.f();
|
|
1594
1795
|
}
|
|
1595
|
-
_loggerProxy.default.logger.info("HashTreeParser#
|
|
1796
|
+
_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
1797
|
return ds.name;
|
|
1597
1798
|
}).join(', ')));
|
|
1598
1799
|
this.state = 'active';
|
|
1599
1800
|
this.handleMessage(message, 'on resume');
|
|
1600
1801
|
}
|
|
1802
|
+
|
|
1803
|
+
/**
|
|
1804
|
+
* Resumes the HashTreeParser that was previously stopped, using a Locus API response.
|
|
1805
|
+
* Unlike resumeFromMessage(), this does not require metadata/dataSets in the input,
|
|
1806
|
+
* as it fetches all necessary information from Locus via initializeFromGetLociResponse.
|
|
1807
|
+
* @param {LocusDTO} locus - locus object from an API response
|
|
1808
|
+
* @returns {Promise}
|
|
1809
|
+
*/
|
|
1810
|
+
}, {
|
|
1811
|
+
key: "resumeFromApiResponse",
|
|
1812
|
+
value: (function () {
|
|
1813
|
+
var _resumeFromApiResponse = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee9(locus) {
|
|
1814
|
+
return _regenerator.default.wrap(function (_context0) {
|
|
1815
|
+
while (1) switch (_context0.prev = _context0.next) {
|
|
1816
|
+
case 0:
|
|
1817
|
+
this.state = 'active';
|
|
1818
|
+
this.dataSets = {};
|
|
1819
|
+
_loggerProxy.default.logger.info("HashTreeParser#resumeFromApiResponse --> ".concat(this.debugId, " Resuming HashTreeParser from API response"));
|
|
1820
|
+
_context0.next = 1;
|
|
1821
|
+
return this.initializeFromGetLociResponse(locus);
|
|
1822
|
+
case 1:
|
|
1823
|
+
case "end":
|
|
1824
|
+
return _context0.stop();
|
|
1825
|
+
}
|
|
1826
|
+
}, _callee9, this);
|
|
1827
|
+
}));
|
|
1828
|
+
function resumeFromApiResponse(_x1) {
|
|
1829
|
+
return _resumeFromApiResponse.apply(this, arguments);
|
|
1830
|
+
}
|
|
1831
|
+
return resumeFromApiResponse;
|
|
1832
|
+
}())
|
|
1601
1833
|
}, {
|
|
1602
1834
|
key: "checkForSentinelHttpResponse",
|
|
1603
1835
|
value: function checkForSentinelHttpResponse(error, dataSetName) {
|
|
1604
1836
|
var _error$body;
|
|
1837
|
+
// 404 for any dataset means the locus is no longer available at this URL - could be replaced or ended
|
|
1838
|
+
// if a dataset is just not visible, we would get a 400
|
|
1839
|
+
if (error.statusCode === 404) {
|
|
1840
|
+
_loggerProxy.default.logger.info("HashTreeParser#checkForSentinelHttpResponse --> ".concat(this.debugId, " Received 404 for data set \"").concat(dataSetName, "\", locus not found"));
|
|
1841
|
+
this.stopAllTimers();
|
|
1842
|
+
throw new LocusNotFoundError();
|
|
1843
|
+
}
|
|
1605
1844
|
var isValidDataSetForSentinel = dataSetName === undefined || PossibleSentinelMessageDataSetNames.includes(dataSetName.toLowerCase());
|
|
1606
|
-
if (
|
|
1607
|
-
|
|
1845
|
+
if (error.statusCode === 409 && ((_error$body = error.body) === null || _error$body === void 0 ? void 0 : _error$body.errorCode) === _types2.LocusErrorCodes.LOCUS_INACTIVE && isValidDataSetForSentinel) {
|
|
1846
|
+
var _error$body2;
|
|
1847
|
+
_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
1848
|
this.stopAllTimers();
|
|
1609
1849
|
throw new MeetingEndedError();
|
|
1610
1850
|
}
|
|
@@ -1614,37 +1854,49 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1614
1854
|
* Gets the current hashes from the locus for a specific data set.
|
|
1615
1855
|
* @param {string} dataSetName
|
|
1616
1856
|
* @param {string} currentRootHash
|
|
1617
|
-
* @returns {
|
|
1857
|
+
* @returns {Object|null} An object containing the hashes and leaf count, or null if the hashes match and no sync is needed
|
|
1618
1858
|
*/
|
|
1619
1859
|
}, {
|
|
1620
1860
|
key: "getHashesFromLocus",
|
|
1621
1861
|
value: function getHashesFromLocus(dataSetName, currentRootHash) {
|
|
1622
|
-
var
|
|
1862
|
+
var _this12 = this;
|
|
1623
1863
|
_loggerProxy.default.logger.info("HashTreeParser#getHashesFromLocus --> ".concat(this.debugId, " Requesting hashes for data set \"").concat(dataSetName, "\""));
|
|
1624
1864
|
var dataSet = this.dataSets[dataSetName];
|
|
1625
1865
|
var url = "".concat(dataSet.url, "/hashtree");
|
|
1626
1866
|
return this.webexRequest({
|
|
1627
|
-
method:
|
|
1867
|
+
method: _constants2.HTTP_VERBS.GET,
|
|
1628
1868
|
uri: url,
|
|
1629
1869
|
qs: {
|
|
1630
1870
|
rootHash: currentRootHash
|
|
1631
1871
|
}
|
|
1632
1872
|
}).then(function (response) {
|
|
1633
1873
|
var _response$body, _response$body2;
|
|
1874
|
+
if (!response.body || (0, _lodash.isEmpty)(response.body)) {
|
|
1875
|
+
// 204 with empty body means our hashes match Locus, no sync needed
|
|
1876
|
+
_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"));
|
|
1877
|
+
return null;
|
|
1878
|
+
}
|
|
1634
1879
|
var hashes = (_response$body = response.body) === null || _response$body === void 0 ? void 0 : _response$body.hashes;
|
|
1635
1880
|
var dataSetFromResponse = (_response$body2 = response.body) === null || _response$body2 === void 0 ? void 0 : _response$body2.dataSet;
|
|
1636
1881
|
if (!hashes || !(0, _isArray.default)(hashes)) {
|
|
1637
|
-
_loggerProxy.default.logger.warn("HashTreeParser#getHashesFromLocus --> ".concat(
|
|
1882
|
+
_loggerProxy.default.logger.warn("HashTreeParser#getHashesFromLocus --> ".concat(_this12.debugId, " Locus returned invalid hashes, response body="), response.body);
|
|
1638
1883
|
throw new Error("Locus returned invalid hashes: ".concat(hashes));
|
|
1639
1884
|
}
|
|
1640
|
-
_loggerProxy.default.logger.info("HashTreeParser#getHashesFromLocus --> ".concat(
|
|
1885
|
+
_loggerProxy.default.logger.info("HashTreeParser#getHashesFromLocus --> ".concat(_this12.debugId, " Received hashes for data set \"").concat(dataSetName, "\": ").concat((0, _stringify.default)(hashes)));
|
|
1641
1886
|
return {
|
|
1642
1887
|
hashes: hashes,
|
|
1643
1888
|
dataSet: dataSetFromResponse
|
|
1644
1889
|
};
|
|
1645
1890
|
}).catch(function (error) {
|
|
1646
|
-
_loggerProxy.default.logger.error("HashTreeParser#getHashesFromLocus --> ".concat(
|
|
1647
|
-
|
|
1891
|
+
_loggerProxy.default.logger.error("HashTreeParser#getHashesFromLocus --> ".concat(_this12.debugId, " Error ").concat(error.statusCode, " fetching hashes for data set \"").concat(dataSetName, "\":"), error);
|
|
1892
|
+
_this12.checkForSentinelHttpResponse(error, dataSet.name);
|
|
1893
|
+
_metrics.default.sendBehavioralMetric(_constants.default.HASH_TREE_SYNC_FAILURE, {
|
|
1894
|
+
debugId: _this12.debugId,
|
|
1895
|
+
dataSetName: dataSetName,
|
|
1896
|
+
request: 'GET /hashtree',
|
|
1897
|
+
statusCode: error.statusCode,
|
|
1898
|
+
reason: error.message
|
|
1899
|
+
});
|
|
1648
1900
|
throw error;
|
|
1649
1901
|
});
|
|
1650
1902
|
}
|
|
@@ -1653,43 +1905,60 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1653
1905
|
* Sends a sync request to Locus for the specified data set.
|
|
1654
1906
|
*
|
|
1655
1907
|
* @param {InternalDataSet} dataSet The data set to sync.
|
|
1656
|
-
* @param {
|
|
1908
|
+
* @param {Object} options Either `{ isInitialization: true }` for init syncs (uses leafCount=1 with empty leaf data) or `{ mismatchedLeavesData }` for normal syncs.
|
|
1657
1909
|
* @returns {Promise<HashTreeMessage|null>}
|
|
1658
1910
|
*/
|
|
1659
1911
|
}, {
|
|
1660
1912
|
key: "sendSyncRequestToLocus",
|
|
1661
|
-
value: function sendSyncRequestToLocus(dataSet,
|
|
1662
|
-
var
|
|
1913
|
+
value: function sendSyncRequestToLocus(dataSet, options) {
|
|
1914
|
+
var _this13 = this;
|
|
1663
1915
|
_loggerProxy.default.logger.info("HashTreeParser#sendSyncRequestToLocus --> ".concat(this.debugId, " Sending sync request for data set \"").concat(dataSet.name, "\""));
|
|
1916
|
+
var isInitialization = 'isInitialization' in options;
|
|
1664
1917
|
var url = "".concat(dataSet.url, "/sync");
|
|
1665
1918
|
var body = {
|
|
1666
|
-
leafCount: dataSet.leafCount,
|
|
1919
|
+
leafCount: isInitialization ? 1 : dataSet.leafCount,
|
|
1667
1920
|
leafDataEntries: []
|
|
1668
1921
|
};
|
|
1669
|
-
|
|
1922
|
+
if (isInitialization) {
|
|
1923
|
+
// initialization sync: Locus requires leafCount=1 with a single empty leaf
|
|
1670
1924
|
body.leafDataEntries.push({
|
|
1671
|
-
leafIndex:
|
|
1672
|
-
elementIds:
|
|
1925
|
+
leafIndex: 0,
|
|
1926
|
+
elementIds: []
|
|
1673
1927
|
});
|
|
1674
|
-
}
|
|
1675
|
-
|
|
1928
|
+
} else {
|
|
1929
|
+
var mismatchedLeavesData = options.mismatchedLeavesData;
|
|
1930
|
+
(0, _keys.default)(mismatchedLeavesData).forEach(function (index) {
|
|
1931
|
+
var leafIndex = (0, _parseInt2.default)(index, 10);
|
|
1932
|
+
body.leafDataEntries.push({
|
|
1933
|
+
leafIndex: leafIndex,
|
|
1934
|
+
elementIds: mismatchedLeavesData[leafIndex]
|
|
1935
|
+
});
|
|
1936
|
+
});
|
|
1937
|
+
}
|
|
1938
|
+
var ourCurrentRootHash = dataSet.hashTree ? dataSet.hashTree.getRootHash() : _constants3.EMPTY_HASH;
|
|
1676
1939
|
return this.webexRequest({
|
|
1677
|
-
method:
|
|
1940
|
+
method: _constants2.HTTP_VERBS.POST,
|
|
1678
1941
|
uri: url,
|
|
1679
1942
|
qs: {
|
|
1680
1943
|
rootHash: ourCurrentRootHash
|
|
1681
1944
|
},
|
|
1682
1945
|
body: body
|
|
1683
1946
|
}).then(function (resp) {
|
|
1684
|
-
_loggerProxy.default.logger.info("HashTreeParser#sendSyncRequestToLocus --> ".concat(_this14.debugId, " Sync request succeeded for \"").concat(dataSet.name, "\""));
|
|
1685
1947
|
if (!resp.body || (0, _lodash.isEmpty)(resp.body)) {
|
|
1686
|
-
_loggerProxy.default.logger.info("HashTreeParser#sendSyncRequestToLocus --> ".concat(
|
|
1948
|
+
_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
1949
|
return null;
|
|
1688
1950
|
}
|
|
1689
1951
|
return resp.body;
|
|
1690
1952
|
}).catch(function (error) {
|
|
1691
|
-
_loggerProxy.default.logger.error("HashTreeParser#sendSyncRequestToLocus --> ".concat(
|
|
1692
|
-
|
|
1953
|
+
_loggerProxy.default.logger.error("HashTreeParser#sendSyncRequestToLocus --> ".concat(_this13.debugId, " Error ").concat(error.statusCode, " sending sync request for data set \"").concat(dataSet.name, "\":"), error);
|
|
1954
|
+
_this13.checkForSentinelHttpResponse(error, dataSet.name);
|
|
1955
|
+
_metrics.default.sendBehavioralMetric(_constants.default.HASH_TREE_SYNC_FAILURE, {
|
|
1956
|
+
debugId: _this13.debugId,
|
|
1957
|
+
dataSetName: dataSet.name,
|
|
1958
|
+
request: 'POST /sync',
|
|
1959
|
+
statusCode: error.statusCode,
|
|
1960
|
+
reason: error.message
|
|
1961
|
+
});
|
|
1693
1962
|
throw error;
|
|
1694
1963
|
});
|
|
1695
1964
|
}
|