@webex/plugin-meetings 3.12.0-next.7 → 3.12.0-next.70
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 +30 -7
- 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 +13 -1
- package/dist/hashTree/constants.js.map +1 -1
- package/dist/hashTree/hashTreeParser.js +880 -382
- package/dist/hashTree/hashTreeParser.js.map +1 -1
- package/dist/hashTree/utils.js +42 -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/dataChannelAuthToken.js +75 -15
- package/dist/interceptors/dataChannelAuthToken.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/interpretation.types.js +7 -0
- package/dist/interpretation/interpretation.types.js.map +1 -0
- 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 +298 -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 +1046 -689
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/muteState.js +10 -1
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.js +5 -2
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/util.js +20 -2
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +2 -2
- package/dist/meeting-info/meeting-info-v2.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 +9 -1
- 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 +2 -0
- package/dist/types/hashTree/hashTreeParser.d.ts +146 -17
- package/dist/types/hashTree/utils.d.ts +18 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/interceptors/locusRetry.d.ts +4 -4
- package/dist/types/interpretation/interpretation.types.d.ts +10 -0
- package/dist/types/locus-info/index.d.ts +50 -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 +78 -5
- package/dist/types/meeting/request.d.ts +1 -0
- 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 +305 -159
- 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 +13 -2
- 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 +16 -0
- package/src/hashTree/hashTreeParser.ts +580 -196
- package/src/hashTree/utils.ts +36 -0
- package/src/index.ts +6 -0
- package/src/interceptors/dataChannelAuthToken.ts +88 -12
- package/src/interceptors/locusRetry.ts +25 -4
- package/src/interpretation/index.ts +27 -9
- package/src/interpretation/interpretation.types.ts +11 -0
- package/src/locus-info/controlsUtils.ts +3 -1
- package/src/locus-info/index.ts +293 -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 +386 -48
- package/src/meeting/muteState.ts +10 -1
- package/src/meeting/request.ts +11 -0
- package/src/meeting/util.ts +21 -2
- package/src/meeting-info/meeting-info-v2.ts +4 -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 +214 -36
- 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 +1838 -180
- package/test/unit/spec/hashTree/utils.ts +125 -1
- package/test/unit/spec/interceptors/dataChannelAuthToken.ts +196 -0
- 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 +487 -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 +1240 -37
- package/test/unit/spec/meeting/muteState.js +81 -0
- package/test/unit/spec/meeting/request.js +12 -0
- package/test/unit/spec/meeting/utils.js +33 -0
- package/test/unit/spec/meeting-info/meetinginfov2.js +19 -10
- 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 +329 -28
|
@@ -15,17 +15,18 @@ 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.SyncAllBackoffType = exports.MeetingEndedError = exports.LocusNotFoundError = exports.LocusInfoUpdateType = void 0;
|
|
19
19
|
var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));
|
|
20
|
-
var
|
|
20
|
+
var _set = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/set"));
|
|
21
21
|
var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));
|
|
22
|
+
var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
|
|
22
23
|
var _isArray = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/array/is-array"));
|
|
23
24
|
var _keys = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/keys"));
|
|
24
25
|
var _values = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/values"));
|
|
25
26
|
var _parseInt2 = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/parse-int"));
|
|
27
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/toConsumableArray"));
|
|
26
28
|
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/slicedToArray"));
|
|
27
29
|
var _typeof2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/typeof"));
|
|
28
|
-
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/toConsumableArray"));
|
|
29
30
|
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/asyncToGenerator"));
|
|
30
31
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
|
|
31
32
|
var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));
|
|
@@ -37,9 +38,12 @@ var _wrapNativeSuper2 = _interopRequireDefault(require("@babel/runtime-corejs2/h
|
|
|
37
38
|
var _lodash = require("lodash");
|
|
38
39
|
var _hashTree = _interopRequireDefault(require("./hashTree"));
|
|
39
40
|
var _loggerProxy = _interopRequireDefault(require("../common/logs/logger-proxy"));
|
|
40
|
-
var
|
|
41
|
-
var
|
|
41
|
+
var _metrics = _interopRequireDefault(require("../metrics"));
|
|
42
|
+
var _constants = _interopRequireDefault(require("../metrics/constants"));
|
|
43
|
+
var _constants2 = require("../constants");
|
|
44
|
+
var _constants3 = require("./constants");
|
|
42
45
|
var _types = require("./types");
|
|
46
|
+
var _types2 = require("../locus-info/types");
|
|
43
47
|
var _utils = require("./utils");
|
|
44
48
|
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
49
|
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; }
|
|
@@ -48,9 +52,16 @@ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r)
|
|
|
48
52
|
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
49
53
|
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? _Reflect$construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
|
|
50
54
|
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
55
|
+
var SyncAllBackoffType = exports.SyncAllBackoffType = /*#__PURE__*/function (SyncAllBackoffType) {
|
|
56
|
+
SyncAllBackoffType["NONE"] = "none";
|
|
57
|
+
SyncAllBackoffType["ONLY_LLM"] = "onlyLLM";
|
|
58
|
+
SyncAllBackoffType["ALL"] = "all";
|
|
59
|
+
return SyncAllBackoffType;
|
|
60
|
+
}({});
|
|
51
61
|
var LocusInfoUpdateType = exports.LocusInfoUpdateType = {
|
|
52
62
|
OBJECTS_UPDATED: 'OBJECTS_UPDATED',
|
|
53
|
-
MEETING_ENDED: 'MEETING_ENDED'
|
|
63
|
+
MEETING_ENDED: 'MEETING_ENDED',
|
|
64
|
+
LOCUS_NOT_FOUND: 'LOCUS_NOT_FOUND'
|
|
54
65
|
};
|
|
55
66
|
/**
|
|
56
67
|
* This error is thrown if we receive information that the meeting has ended while we're processing some hash messages.
|
|
@@ -64,11 +75,24 @@ var MeetingEndedError = exports.MeetingEndedError = /*#__PURE__*/function (_Erro
|
|
|
64
75
|
(0, _inherits2.default)(MeetingEndedError, _Error);
|
|
65
76
|
return (0, _createClass2.default)(MeetingEndedError);
|
|
66
77
|
}(/*#__PURE__*/(0, _wrapNativeSuper2.default)(Error));
|
|
78
|
+
/**
|
|
79
|
+
* This error is thrown when a 404 is received from Locus hash tree endpoints, indicating that the locus URL
|
|
80
|
+
* is no longer valid (e.g. participant moved to a breakout room, or meeting ended).
|
|
81
|
+
* It's handled internally by HashTreeParser and results in LOCUS_NOT_FOUND being sent up.
|
|
82
|
+
*/
|
|
83
|
+
var LocusNotFoundError = exports.LocusNotFoundError = /*#__PURE__*/function (_Error2) {
|
|
84
|
+
function LocusNotFoundError() {
|
|
85
|
+
(0, _classCallCheck2.default)(this, LocusNotFoundError);
|
|
86
|
+
return _callSuper(this, LocusNotFoundError, arguments);
|
|
87
|
+
}
|
|
88
|
+
(0, _inherits2.default)(LocusNotFoundError, _Error2);
|
|
89
|
+
return (0, _createClass2.default)(LocusNotFoundError);
|
|
90
|
+
}(/*#__PURE__*/(0, _wrapNativeSuper2.default)(Error));
|
|
67
91
|
/* Currently Locus always sends Metadata objects only in the "self" dataset.
|
|
68
92
|
* If this ever changes, update all the code that relies on this constant.
|
|
69
93
|
*/
|
|
70
|
-
var MetadataDataSetName =
|
|
71
|
-
var PossibleSentinelMessageDataSetNames = [
|
|
94
|
+
var MetadataDataSetName = _constants3.DataSetNames.SELF;
|
|
95
|
+
var PossibleSentinelMessageDataSetNames = [_constants3.DataSetNames.MAIN, _constants3.DataSetNames.SELF, _constants3.DataSetNames.UNJOINED];
|
|
72
96
|
|
|
73
97
|
/**
|
|
74
98
|
* Parses hash tree eventing locus data
|
|
@@ -89,9 +113,17 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
89
113
|
(0, _defineProperty2.default)(this, "locusInfoUpdateCallback", void 0);
|
|
90
114
|
(0, _defineProperty2.default)(this, "visibleDataSets", void 0);
|
|
91
115
|
(0, _defineProperty2.default)(this, "debugId", void 0);
|
|
92
|
-
(0, _defineProperty2.default)(this, "heartbeatIntervalMs", void 0);
|
|
93
116
|
(0, _defineProperty2.default)(this, "excludedDataSets", void 0);
|
|
94
117
|
(0, _defineProperty2.default)(this, "state", void 0);
|
|
118
|
+
(0, _defineProperty2.default)(this, "syncQueue", []);
|
|
119
|
+
(0, _defineProperty2.default)(this, "isSyncInProgress", false);
|
|
120
|
+
// tracks whether syncAllDatasets is currently in its backoff delay phase and with what scope
|
|
121
|
+
(0, _defineProperty2.default)(this, "syncAllBackoffType", SyncAllBackoffType.NONE);
|
|
122
|
+
// datasets that received messages during the syncAllDatasets backoff sleep and should be skipped
|
|
123
|
+
(0, _defineProperty2.default)(this, "dataSetsSyncedDuringBackoff", new _set.default());
|
|
124
|
+
(0, _defineProperty2.default)(this, "syncQueueProcessingPromise", _promise.default.resolve());
|
|
125
|
+
// top-level heartbeat interval from the most recent message, used as fallback when dataset-level value is missing
|
|
126
|
+
(0, _defineProperty2.default)(this, "topLevelHeartbeatIntervalMs", void 0);
|
|
95
127
|
var _options$initialLocus = options.initialLocus,
|
|
96
128
|
dataSets = _options$initialLocus.dataSets,
|
|
97
129
|
locus = _options$initialLocus.locus; // extract dataSets from initialLocus
|
|
@@ -212,80 +244,65 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
212
244
|
*/
|
|
213
245
|
}, {
|
|
214
246
|
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);
|
|
247
|
+
value: (function () {
|
|
248
|
+
var _initializeNewVisibleDataSet = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee(visibleDataSetInfo, dataSetInfo) {
|
|
249
|
+
var hashTree;
|
|
250
|
+
return _regenerator.default.wrap(function (_context) {
|
|
251
|
+
while (1) switch (_context.prev = _context.next) {
|
|
252
|
+
case 0:
|
|
253
|
+
if (!this.isVisibleDataSet(dataSetInfo.name)) {
|
|
254
|
+
_context.next = 1;
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
257
|
+
_loggerProxy.default.logger.info("HashTreeParser#initializeNewVisibleDataSet --> ".concat(this.debugId, " Data set \"").concat(dataSetInfo.name, "\" already exists, skipping init"));
|
|
258
|
+
return _context.abrupt("return");
|
|
259
|
+
case 1:
|
|
260
|
+
_loggerProxy.default.logger.info("HashTreeParser#initializeNewVisibleDataSet --> ".concat(this.debugId, " Adding visible data set \"").concat(dataSetInfo.name, "\""));
|
|
261
|
+
if (this.addToVisibleDataSetsList(visibleDataSetInfo)) {
|
|
262
|
+
_context.next = 2;
|
|
263
|
+
break;
|
|
264
|
+
}
|
|
265
|
+
return _context.abrupt("return");
|
|
266
|
+
case 2:
|
|
267
|
+
hashTree = new _hashTree.default([], dataSetInfo.leafCount);
|
|
268
|
+
this.dataSets[dataSetInfo.name] = _objectSpread(_objectSpread({}, dataSetInfo), {}, {
|
|
269
|
+
hashTree: hashTree
|
|
270
|
+
});
|
|
271
|
+
this.enqueueSyncForDataset(dataSetInfo.name, 'new visible data set initialization', true);
|
|
272
|
+
_context.next = 3;
|
|
273
|
+
return this.syncQueueProcessingPromise;
|
|
274
|
+
case 3:
|
|
275
|
+
case "end":
|
|
276
|
+
return _context.stop();
|
|
277
|
+
}
|
|
278
|
+
}, _callee, this);
|
|
279
|
+
}));
|
|
280
|
+
function initializeNewVisibleDataSet(_x, _x2) {
|
|
281
|
+
return _initializeNewVisibleDataSet.apply(this, arguments);
|
|
252
282
|
}
|
|
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
|
-
|
|
283
|
+
return initializeNewVisibleDataSet;
|
|
284
|
+
}()
|
|
269
285
|
/**
|
|
270
286
|
* Queries Locus for all up-to-date information about all visible data sets
|
|
271
287
|
*
|
|
272
288
|
* @returns {Promise}
|
|
273
289
|
*/
|
|
290
|
+
)
|
|
274
291
|
}, {
|
|
275
292
|
key: "getAllVisibleDataSetsFromLocus",
|
|
276
293
|
value: function getAllVisibleDataSetsFromLocus() {
|
|
277
|
-
var
|
|
294
|
+
var _this2 = this;
|
|
278
295
|
if (!this.visibleDataSetsUrl) {
|
|
279
296
|
_loggerProxy.default.logger.warn("HashTreeParser#getAllVisibleDataSetsFromLocus --> ".concat(this.debugId, " No visibleDataSetsUrl, cannot get data sets information"));
|
|
280
297
|
return _promise.default.resolve([]);
|
|
281
298
|
}
|
|
282
299
|
return this.webexRequest({
|
|
283
|
-
method:
|
|
300
|
+
method: _constants2.HTTP_VERBS.GET,
|
|
284
301
|
uri: this.visibleDataSetsUrl
|
|
285
302
|
}).then(function (response) {
|
|
286
303
|
return response.body.dataSets;
|
|
287
304
|
}).catch(function (error) {
|
|
288
|
-
|
|
305
|
+
_this2.checkForSentinelHttpResponse(error);
|
|
289
306
|
throw error;
|
|
290
307
|
});
|
|
291
308
|
}
|
|
@@ -299,26 +316,26 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
299
316
|
}, {
|
|
300
317
|
key: "initializeFromMessage",
|
|
301
318
|
value: (function () {
|
|
302
|
-
var _initializeFromMessage = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function
|
|
319
|
+
var _initializeFromMessage = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee2(message) {
|
|
303
320
|
var visibleDataSets;
|
|
304
|
-
return _regenerator.default.wrap(function (
|
|
305
|
-
while (1) switch (
|
|
321
|
+
return _regenerator.default.wrap(function (_context2) {
|
|
322
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
306
323
|
case 0:
|
|
307
324
|
this.visibleDataSetsUrl = message.visibleDataSetsUrl;
|
|
308
325
|
_loggerProxy.default.logger.info("HashTreeParser#initializeFromMessage --> ".concat(this.debugId, " visibleDataSetsUrl=").concat(this.visibleDataSetsUrl));
|
|
309
|
-
|
|
326
|
+
_context2.next = 1;
|
|
310
327
|
return this.getAllVisibleDataSetsFromLocus();
|
|
311
328
|
case 1:
|
|
312
|
-
visibleDataSets =
|
|
313
|
-
|
|
329
|
+
visibleDataSets = _context2.sent;
|
|
330
|
+
_context2.next = 2;
|
|
314
331
|
return this.initializeDataSets(visibleDataSets, 'initialization from message');
|
|
315
332
|
case 2:
|
|
316
333
|
case "end":
|
|
317
|
-
return
|
|
334
|
+
return _context2.stop();
|
|
318
335
|
}
|
|
319
|
-
},
|
|
336
|
+
}, _callee2, this);
|
|
320
337
|
}));
|
|
321
|
-
function initializeFromMessage(
|
|
338
|
+
function initializeFromMessage(_x3) {
|
|
322
339
|
return _initializeFromMessage.apply(this, arguments);
|
|
323
340
|
}
|
|
324
341
|
return initializeFromMessage;
|
|
@@ -336,34 +353,34 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
336
353
|
}, {
|
|
337
354
|
key: "initializeFromGetLociResponse",
|
|
338
355
|
value: (function () {
|
|
339
|
-
var _initializeFromGetLociResponse = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function
|
|
356
|
+
var _initializeFromGetLociResponse = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee3(locus) {
|
|
340
357
|
var _locus$links2, _locus$links2$resourc, _locus$links2$resourc2;
|
|
341
358
|
var visibleDataSets;
|
|
342
|
-
return _regenerator.default.wrap(function (
|
|
343
|
-
while (1) switch (
|
|
359
|
+
return _regenerator.default.wrap(function (_context3) {
|
|
360
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
344
361
|
case 0:
|
|
345
362
|
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
|
-
|
|
363
|
+
_context3.next = 1;
|
|
347
364
|
break;
|
|
348
365
|
}
|
|
349
366
|
_loggerProxy.default.logger.warn("HashTreeParser#initializeFromGetLociResponse --> ".concat(this.debugId, " missing visibleDataSets url in GET Loci response, cannot initialize hash trees"));
|
|
350
|
-
return
|
|
367
|
+
return _context3.abrupt("return");
|
|
351
368
|
case 1:
|
|
352
369
|
this.visibleDataSetsUrl = locus.links.resources.visibleDataSets.url;
|
|
353
370
|
_loggerProxy.default.logger.info("HashTreeParser#initializeFromGetLociResponse --> ".concat(this.debugId, " visibleDataSets url: ").concat(this.visibleDataSetsUrl));
|
|
354
|
-
|
|
371
|
+
_context3.next = 2;
|
|
355
372
|
return this.getAllVisibleDataSetsFromLocus();
|
|
356
373
|
case 2:
|
|
357
|
-
visibleDataSets =
|
|
358
|
-
|
|
374
|
+
visibleDataSets = _context3.sent;
|
|
375
|
+
_context3.next = 3;
|
|
359
376
|
return this.initializeDataSets(visibleDataSets, 'initialization from GET /loci response');
|
|
360
377
|
case 3:
|
|
361
378
|
case "end":
|
|
362
|
-
return
|
|
379
|
+
return _context3.stop();
|
|
363
380
|
}
|
|
364
|
-
},
|
|
381
|
+
}, _callee3, this);
|
|
365
382
|
}));
|
|
366
|
-
function initializeFromGetLociResponse(
|
|
383
|
+
function initializeFromGetLociResponse(_x4) {
|
|
367
384
|
return _initializeFromGetLociResponse.apply(this, arguments);
|
|
368
385
|
}
|
|
369
386
|
return initializeFromGetLociResponse;
|
|
@@ -379,24 +396,23 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
379
396
|
}, {
|
|
380
397
|
key: "initializeDataSets",
|
|
381
398
|
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 (
|
|
399
|
+
var _initializeDataSets = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee4(visibleDataSets, debugText) {
|
|
400
|
+
var _iterator2, _step2, dataSet, name, leafCount, url, _t;
|
|
401
|
+
return _regenerator.default.wrap(function (_context4) {
|
|
402
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
386
403
|
case 0:
|
|
387
404
|
if (!(this.state === 'stopped')) {
|
|
388
|
-
|
|
405
|
+
_context4.next = 1;
|
|
389
406
|
break;
|
|
390
407
|
}
|
|
391
|
-
return
|
|
408
|
+
return _context4.abrupt("return");
|
|
392
409
|
case 1:
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
_context3.prev = 2;
|
|
410
|
+
_iterator2 = _createForOfIteratorHelper((0, _utils.sortByInitPriority)(visibleDataSets, _constants3.DATA_SET_INIT_PRIORITY));
|
|
411
|
+
_context4.prev = 2;
|
|
396
412
|
_iterator2.s();
|
|
397
413
|
case 3:
|
|
398
414
|
if ((_step2 = _iterator2.n()).done) {
|
|
399
|
-
|
|
415
|
+
_context4.next = 6;
|
|
400
416
|
break;
|
|
401
417
|
}
|
|
402
418
|
dataSet = _step2.value;
|
|
@@ -408,59 +424,47 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
408
424
|
_loggerProxy.default.logger.info("HashTreeParser#initializeDataSets --> ".concat(this.debugId, " dataset \"").concat(name, "\" already exists (").concat(debugText, ")"));
|
|
409
425
|
}
|
|
410
426
|
if (this.isVisibleDataSet(name)) {
|
|
411
|
-
|
|
427
|
+
_context4.next = 4;
|
|
412
428
|
break;
|
|
413
429
|
}
|
|
414
430
|
if (this.addToVisibleDataSetsList({
|
|
415
431
|
name: name,
|
|
416
432
|
url: url
|
|
417
433
|
})) {
|
|
418
|
-
|
|
434
|
+
_context4.next = 4;
|
|
419
435
|
break;
|
|
420
436
|
}
|
|
421
|
-
return
|
|
437
|
+
return _context4.abrupt("continue", 5);
|
|
422
438
|
case 4:
|
|
423
|
-
if (this.dataSets[name].hashTree) {
|
|
424
|
-
|
|
425
|
-
|
|
439
|
+
if (!this.dataSets[name].hashTree) {
|
|
440
|
+
_loggerProxy.default.logger.info("HashTreeParser#initializeDataSets --> ".concat(this.debugId, " creating hash tree for visible dataset \"").concat(name, "\" (").concat(debugText, ")"));
|
|
441
|
+
this.dataSets[name].hashTree = new _hashTree.default([], leafCount);
|
|
442
|
+
this.enqueueSyncForDataset(name, "initialization sync for ".concat(debugText), true);
|
|
426
443
|
}
|
|
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
444
|
case 5:
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
updatedObjects.push.apply(updatedObjects, (0, _toConsumableArray2.default)(_data.updatedObjects || []));
|
|
437
|
-
}
|
|
445
|
+
_context4.next = 3;
|
|
446
|
+
break;
|
|
438
447
|
case 6:
|
|
439
|
-
|
|
448
|
+
_context4.next = 8;
|
|
440
449
|
break;
|
|
441
450
|
case 7:
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
case 8:
|
|
445
|
-
_context3.prev = 8;
|
|
446
|
-
_t = _context3["catch"](2);
|
|
451
|
+
_context4.prev = 7;
|
|
452
|
+
_t = _context4["catch"](2);
|
|
447
453
|
_iterator2.e(_t);
|
|
448
|
-
case
|
|
449
|
-
|
|
454
|
+
case 8:
|
|
455
|
+
_context4.prev = 8;
|
|
450
456
|
_iterator2.f();
|
|
451
|
-
return
|
|
457
|
+
return _context4.finish(8);
|
|
458
|
+
case 9:
|
|
459
|
+
_context4.next = 10;
|
|
460
|
+
return this.syncQueueProcessingPromise;
|
|
452
461
|
case 10:
|
|
453
|
-
this.callLocusInfoUpdateCallback({
|
|
454
|
-
updateType: LocusInfoUpdateType.OBJECTS_UPDATED,
|
|
455
|
-
updatedObjects: updatedObjects
|
|
456
|
-
});
|
|
457
|
-
case 11:
|
|
458
462
|
case "end":
|
|
459
|
-
return
|
|
463
|
+
return _context4.stop();
|
|
460
464
|
}
|
|
461
|
-
},
|
|
465
|
+
}, _callee4, this, [[2, 7, 8, 9]]);
|
|
462
466
|
}));
|
|
463
|
-
function initializeDataSets(
|
|
467
|
+
function initializeDataSets(_x5, _x6) {
|
|
464
468
|
return _initializeDataSets.apply(this, arguments);
|
|
465
469
|
}
|
|
466
470
|
return initializeDataSets;
|
|
@@ -596,9 +600,9 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
596
600
|
}, {
|
|
597
601
|
key: "isEndMessage",
|
|
598
602
|
value: function isEndMessage(message) {
|
|
599
|
-
var
|
|
603
|
+
var _this3 = this;
|
|
600
604
|
return message.dataSets.some(function (dataSet) {
|
|
601
|
-
if (dataSet.leafCount === 1 && dataSet.root ===
|
|
605
|
+
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
606
|
// this is a special way for Locus to indicate that this meeting has ended
|
|
603
607
|
return true;
|
|
604
608
|
}
|
|
@@ -615,7 +619,7 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
615
619
|
}, {
|
|
616
620
|
key: "handleRootHashHeartBeatMessage",
|
|
617
621
|
value: function handleRootHashHeartBeatMessage(message) {
|
|
618
|
-
var
|
|
622
|
+
var _this4 = this;
|
|
619
623
|
var dataSets = message.dataSets;
|
|
620
624
|
_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
625
|
var name = _ref2.name,
|
|
@@ -629,12 +633,40 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
629
633
|
version: version
|
|
630
634
|
};
|
|
631
635
|
}))));
|
|
636
|
+
this.cancelPendingSyncsForDataSets(dataSets.map(function (ds) {
|
|
637
|
+
return ds.name;
|
|
638
|
+
}));
|
|
632
639
|
dataSets.forEach(function (dataSet) {
|
|
633
|
-
|
|
634
|
-
|
|
640
|
+
_this4.updateDataSetInfo(dataSet);
|
|
641
|
+
_this4.runSyncAlgorithm(dataSet);
|
|
635
642
|
});
|
|
636
643
|
}
|
|
637
644
|
|
|
645
|
+
/**
|
|
646
|
+
* Handles known errors that can happen during syncs
|
|
647
|
+
*
|
|
648
|
+
* @param {any} error - The error to handle
|
|
649
|
+
* @returns {boolean} true if the error was recognized and handled, false otherwise
|
|
650
|
+
*/
|
|
651
|
+
}, {
|
|
652
|
+
key: "handleSyncErrors",
|
|
653
|
+
value: function handleSyncErrors(error) {
|
|
654
|
+
if (error instanceof MeetingEndedError) {
|
|
655
|
+
this.callLocusInfoUpdateCallback({
|
|
656
|
+
updateType: LocusInfoUpdateType.MEETING_ENDED
|
|
657
|
+
});
|
|
658
|
+
return true;
|
|
659
|
+
}
|
|
660
|
+
if (error instanceof LocusNotFoundError) {
|
|
661
|
+
this.callLocusInfoUpdateCallback({
|
|
662
|
+
updateType: LocusInfoUpdateType.LOCUS_NOT_FOUND
|
|
663
|
+
});
|
|
664
|
+
this.stop();
|
|
665
|
+
return true;
|
|
666
|
+
}
|
|
667
|
+
return false;
|
|
668
|
+
}
|
|
669
|
+
|
|
638
670
|
/**
|
|
639
671
|
* Asynchronously initializes new visible data sets
|
|
640
672
|
*
|
|
@@ -644,18 +676,14 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
644
676
|
}, {
|
|
645
677
|
key: "queueInitForNewVisibleDataSets",
|
|
646
678
|
value: function queueInitForNewVisibleDataSets(dataSetsRequiringInitialization) {
|
|
647
|
-
var
|
|
679
|
+
var _this5 = this;
|
|
648
680
|
_loggerProxy.default.logger.info("HashTreeParser#queueInitForNewVisibleDataSets --> ".concat(this.debugId, " queuing initialization of new visible datasets: ").concat(dataSetsRequiringInitialization.map(function (ds) {
|
|
649
681
|
return ds.name;
|
|
650
682
|
}).join(', ')));
|
|
651
683
|
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) {
|
|
684
|
+
_this5.initializeNewVisibleDataSets(dataSetsRequiringInitialization).catch(function (error) {
|
|
685
|
+
if (!_this5.handleSyncErrors(error)) {
|
|
686
|
+
_loggerProxy.default.logger.warn("HashTreeParser#queueInitForNewVisibleDataSets --> ".concat(_this5.debugId, " error while initializing new visible datasets: ").concat(dataSetsRequiringInitialization.map(function (ds) {
|
|
659
687
|
return ds.name;
|
|
660
688
|
}).join(', '), ": "), error);
|
|
661
689
|
}
|
|
@@ -715,14 +743,18 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
715
743
|
}, {
|
|
716
744
|
key: "handleLocusUpdate",
|
|
717
745
|
value: function handleLocusUpdate(update) {
|
|
718
|
-
var
|
|
746
|
+
var _this6 = this;
|
|
719
747
|
if (this.state === 'stopped') {
|
|
720
748
|
return;
|
|
721
749
|
}
|
|
722
750
|
var dataSets = update.dataSets,
|
|
723
751
|
locus = update.locus,
|
|
724
752
|
metadata = update.metadata;
|
|
753
|
+
_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) {
|
|
754
|
+
return ds.name;
|
|
755
|
+
}).join(','), " metadata=").concat(metadata ? 'yes' : 'no'));
|
|
725
756
|
if (!dataSets) {
|
|
757
|
+
// this happens for example when we handle GET /loci response
|
|
726
758
|
_loggerProxy.default.logger.info("HashTreeParser#handleLocusUpdate --> ".concat(this.debugId, " received hash tree update without dataSets"));
|
|
727
759
|
} else {
|
|
728
760
|
var _iterator5 = _createForOfIteratorHelper(dataSets),
|
|
@@ -752,9 +784,9 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
752
784
|
|
|
753
785
|
// then process the data in hash trees, if it is a new version, then add it to updatedObjects
|
|
754
786
|
(0, _keys.default)(leafInfo).forEach(function (dataSetName) {
|
|
755
|
-
if (
|
|
756
|
-
if (
|
|
757
|
-
var appliedChangesList =
|
|
787
|
+
if (_this6.dataSets[dataSetName]) {
|
|
788
|
+
if (_this6.dataSets[dataSetName].hashTree) {
|
|
789
|
+
var appliedChangesList = _this6.dataSets[dataSetName].hashTree.putItems(leafInfo[dataSetName].map(function (leaf) {
|
|
758
790
|
return {
|
|
759
791
|
id: leaf.id,
|
|
760
792
|
type: leaf.type,
|
|
@@ -781,10 +813,10 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
781
813
|
});
|
|
782
814
|
} else {
|
|
783
815
|
// no hash tree means that the data set is not visible
|
|
784
|
-
_loggerProxy.default.logger.warn("HashTreeParser#handleLocusUpdate --> ".concat(
|
|
816
|
+
_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
817
|
}
|
|
786
818
|
} else {
|
|
787
|
-
_loggerProxy.default.logger.info("HashTreeParser#handleLocusUpdate --> ".concat(
|
|
819
|
+
_loggerProxy.default.logger.info("HashTreeParser#handleLocusUpdate --> ".concat(_this6.debugId, " received leaf data for unknown data set \"").concat(dataSetName, "\", ignoring"));
|
|
788
820
|
}
|
|
789
821
|
});
|
|
790
822
|
if (updatedObjects.length === 0) {
|
|
@@ -820,10 +852,26 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
820
852
|
maxMs: receivedDataSet.backoff.maxMs,
|
|
821
853
|
exponent: receivedDataSet.backoff.exponent
|
|
822
854
|
};
|
|
855
|
+
this.dataSets[receivedDataSet.name].heartbeatIntervalMs = receivedDataSet.heartbeatIntervalMs;
|
|
823
856
|
_loggerProxy.default.logger.info("HashTreeParser#updateDataSetInfo --> ".concat(this.debugId, " updated \"").concat(receivedDataSet.name, "\" dataset to version=").concat(receivedDataSet.version, ", root=").concat(receivedDataSet.root));
|
|
824
857
|
}
|
|
825
858
|
}
|
|
826
859
|
|
|
860
|
+
/**
|
|
861
|
+
* Updates the leaf count for a data set, resizing its hash tree accordingly.
|
|
862
|
+
*
|
|
863
|
+
* @param {InternalDataSet} dataSet - The data set to update
|
|
864
|
+
* @param {number} newLeafCount - The new leaf count
|
|
865
|
+
* @returns {void}
|
|
866
|
+
*/
|
|
867
|
+
}, {
|
|
868
|
+
key: "updateDataSetLeafCount",
|
|
869
|
+
value: function updateDataSetLeafCount(dataSet, newLeafCount) {
|
|
870
|
+
var _dataSet$hashTree;
|
|
871
|
+
(_dataSet$hashTree = dataSet.hashTree) === null || _dataSet$hashTree === void 0 ? void 0 : _dataSet$hashTree.resize(newLeafCount);
|
|
872
|
+
dataSet.leafCount = newLeafCount;
|
|
873
|
+
}
|
|
874
|
+
|
|
827
875
|
/**
|
|
828
876
|
* Checks for changes in the visible data sets based on the updated objects.
|
|
829
877
|
* @param {HashTreeObject[]} updatedObjects - The list of updated hash tree objects.
|
|
@@ -832,7 +880,7 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
832
880
|
}, {
|
|
833
881
|
key: "checkForVisibleDataSetChanges",
|
|
834
882
|
value: function checkForVisibleDataSetChanges(updatedObjects) {
|
|
835
|
-
var
|
|
883
|
+
var _this7 = this;
|
|
836
884
|
var removedDataSets = [];
|
|
837
885
|
var addedDataSets = [];
|
|
838
886
|
|
|
@@ -841,20 +889,20 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
841
889
|
var _object$data;
|
|
842
890
|
if ((0, _utils.isMetadata)(object) && (_object$data = object.data) !== null && _object$data !== void 0 && _object$data.visibleDataSets) {
|
|
843
891
|
var newVisibleDataSets = object.data.visibleDataSets.filter(function (vds) {
|
|
844
|
-
return !
|
|
892
|
+
return !_this7.isExcludedDataSet(vds.name);
|
|
845
893
|
});
|
|
846
|
-
removedDataSets =
|
|
894
|
+
removedDataSets = _this7.visibleDataSets.filter(function (ds) {
|
|
847
895
|
return !newVisibleDataSets.some(function (nvs) {
|
|
848
896
|
return nvs.name === ds.name;
|
|
849
897
|
});
|
|
850
898
|
});
|
|
851
899
|
addedDataSets = newVisibleDataSets.filter(function (nvs) {
|
|
852
|
-
return
|
|
900
|
+
return _this7.visibleDataSets.every(function (ds) {
|
|
853
901
|
return ds.name !== nvs.name;
|
|
854
902
|
});
|
|
855
903
|
});
|
|
856
904
|
if (removedDataSets.length > 0 || addedDataSets.length > 0) {
|
|
857
|
-
_loggerProxy.default.logger.info("HashTreeParser#checkForVisibleDataSetChanges --> ".concat(
|
|
905
|
+
_loggerProxy.default.logger.info("HashTreeParser#checkForVisibleDataSetChanges --> ".concat(_this7.debugId, " visible data sets change: removed: ").concat(removedDataSets.map(function (ds) {
|
|
858
906
|
return ds.name;
|
|
859
907
|
}).join(', '), ", added: ").concat(addedDataSets.map(function (ds) {
|
|
860
908
|
return ds.name;
|
|
@@ -878,7 +926,10 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
878
926
|
}, {
|
|
879
927
|
key: "deleteHashTree",
|
|
880
928
|
value: function deleteHashTree(dataSetName) {
|
|
929
|
+
var _this$dataSets$dataSe;
|
|
881
930
|
this.dataSets[dataSetName].hashTree = undefined;
|
|
931
|
+
(_this$dataSets$dataSe = this.dataSets[dataSetName].syncAbortController) === null || _this$dataSets$dataSe === void 0 ? void 0 : _this$dataSets$dataSe.abort();
|
|
932
|
+
this.dataSets[dataSetName].syncAbortController = undefined;
|
|
882
933
|
|
|
883
934
|
// we also need to stop the timers as there is no hash tree anymore to sync
|
|
884
935
|
if (this.dataSets[dataSetName].timer) {
|
|
@@ -908,16 +959,16 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
908
959
|
}, {
|
|
909
960
|
key: "processVisibleDataSetChanges",
|
|
910
961
|
value: function processVisibleDataSetChanges(removedDataSets, addedDataSets, updatedObjects) {
|
|
911
|
-
var
|
|
962
|
+
var _this8 = this;
|
|
912
963
|
var dataSetsRequiringInitialization = [];
|
|
913
964
|
|
|
914
965
|
// if a visible data set was removed, we need to tell our client that all objects from it are removed
|
|
915
966
|
var removedObjects = [];
|
|
916
967
|
removedDataSets.forEach(function (ds) {
|
|
917
|
-
var
|
|
918
|
-
if ((
|
|
919
|
-
for (var i = 0; i <
|
|
920
|
-
removedObjects.push.apply(removedObjects, (0, _toConsumableArray2.default)(
|
|
968
|
+
var _this8$dataSets$ds$na;
|
|
969
|
+
if ((_this8$dataSets$ds$na = _this8.dataSets[ds.name]) !== null && _this8$dataSets$ds$na !== void 0 && _this8$dataSets$ds$na.hashTree) {
|
|
970
|
+
for (var i = 0; i < _this8.dataSets[ds.name].hashTree.numLeaves; i += 1) {
|
|
971
|
+
removedObjects.push.apply(removedObjects, (0, _toConsumableArray2.default)(_this8.dataSets[ds.name].hashTree.getLeafData(i).map(function (elementId) {
|
|
921
972
|
return {
|
|
922
973
|
htMeta: {
|
|
923
974
|
elementId: elementId,
|
|
@@ -927,7 +978,7 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
927
978
|
};
|
|
928
979
|
})));
|
|
929
980
|
}
|
|
930
|
-
|
|
981
|
+
_this8.deleteHashTree(ds.name);
|
|
931
982
|
}
|
|
932
983
|
});
|
|
933
984
|
this.visibleDataSets = this.visibleDataSets.filter(function (vds) {
|
|
@@ -988,81 +1039,78 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
988
1039
|
}, {
|
|
989
1040
|
key: "initializeNewVisibleDataSets",
|
|
990
1041
|
value: (function () {
|
|
991
|
-
var _initializeNewVisibleDataSets = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function
|
|
992
|
-
var
|
|
1042
|
+
var _initializeNewVisibleDataSets = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee5(addedDataSets) {
|
|
1043
|
+
var _this9 = this;
|
|
993
1044
|
var allDataSets, _iterator7, _step7, _loop, _t2;
|
|
994
|
-
return _regenerator.default.wrap(function (
|
|
995
|
-
while (1) switch (
|
|
1045
|
+
return _regenerator.default.wrap(function (_context6) {
|
|
1046
|
+
while (1) switch (_context6.prev = _context6.next) {
|
|
996
1047
|
case 0:
|
|
997
1048
|
if (!(this.state === 'stopped')) {
|
|
998
|
-
|
|
1049
|
+
_context6.next = 1;
|
|
999
1050
|
break;
|
|
1000
1051
|
}
|
|
1001
|
-
return
|
|
1052
|
+
return _context6.abrupt("return");
|
|
1002
1053
|
case 1:
|
|
1003
|
-
|
|
1054
|
+
_context6.next = 2;
|
|
1004
1055
|
return this.getAllVisibleDataSetsFromLocus();
|
|
1005
1056
|
case 2:
|
|
1006
|
-
allDataSets =
|
|
1007
|
-
_iterator7 = _createForOfIteratorHelper(addedDataSets);
|
|
1008
|
-
|
|
1057
|
+
allDataSets = _context6.sent;
|
|
1058
|
+
_iterator7 = _createForOfIteratorHelper((0, _utils.sortByInitPriority)(addedDataSets, _constants3.DATA_SET_INIT_PRIORITY));
|
|
1059
|
+
_context6.prev = 3;
|
|
1009
1060
|
_loop = /*#__PURE__*/_regenerator.default.mark(function _loop() {
|
|
1010
|
-
var ds, dataSetInfo
|
|
1011
|
-
return _regenerator.default.wrap(function (
|
|
1012
|
-
while (1) switch (
|
|
1061
|
+
var ds, dataSetInfo;
|
|
1062
|
+
return _regenerator.default.wrap(function (_context5) {
|
|
1063
|
+
while (1) switch (_context5.prev = _context5.next) {
|
|
1013
1064
|
case 0:
|
|
1014
1065
|
ds = _step7.value;
|
|
1015
1066
|
dataSetInfo = allDataSets.find(function (d) {
|
|
1016
1067
|
return d.name === ds.name;
|
|
1017
1068
|
});
|
|
1018
|
-
_loggerProxy.default.logger.info("HashTreeParser#initializeNewVisibleDataSets --> ".concat(
|
|
1069
|
+
_loggerProxy.default.logger.info("HashTreeParser#initializeNewVisibleDataSets --> ".concat(_this9.debugId, " initializing data set \"").concat(ds.name, "\""));
|
|
1019
1070
|
if (dataSetInfo) {
|
|
1020
|
-
|
|
1071
|
+
_context5.next = 1;
|
|
1021
1072
|
break;
|
|
1022
1073
|
}
|
|
1023
|
-
_loggerProxy.default.logger.warn("HashTreeParser#initializeNewVisibleDataSets --> ".concat(
|
|
1024
|
-
|
|
1074
|
+
_loggerProxy.default.logger.warn("HashTreeParser#initializeNewVisibleDataSets --> ".concat(_this9.debugId, " missing info about data set \"").concat(ds.name, "\" in Locus response from visibleDataSetsUrl"));
|
|
1075
|
+
_context5.next = 2;
|
|
1025
1076
|
break;
|
|
1026
1077
|
case 1:
|
|
1027
|
-
|
|
1028
|
-
return
|
|
1078
|
+
_context5.next = 2;
|
|
1079
|
+
return _this9.initializeNewVisibleDataSet(ds, dataSetInfo);
|
|
1029
1080
|
case 2:
|
|
1030
|
-
updates = _context4.sent;
|
|
1031
|
-
_this0.callLocusInfoUpdateCallback(updates);
|
|
1032
|
-
case 3:
|
|
1033
1081
|
case "end":
|
|
1034
|
-
return
|
|
1082
|
+
return _context5.stop();
|
|
1035
1083
|
}
|
|
1036
1084
|
}, _loop);
|
|
1037
1085
|
});
|
|
1038
1086
|
_iterator7.s();
|
|
1039
1087
|
case 4:
|
|
1040
1088
|
if ((_step7 = _iterator7.n()).done) {
|
|
1041
|
-
|
|
1089
|
+
_context6.next = 6;
|
|
1042
1090
|
break;
|
|
1043
1091
|
}
|
|
1044
|
-
return
|
|
1092
|
+
return _context6.delegateYield(_loop(), "t0", 5);
|
|
1045
1093
|
case 5:
|
|
1046
|
-
|
|
1094
|
+
_context6.next = 4;
|
|
1047
1095
|
break;
|
|
1048
1096
|
case 6:
|
|
1049
|
-
|
|
1097
|
+
_context6.next = 8;
|
|
1050
1098
|
break;
|
|
1051
1099
|
case 7:
|
|
1052
|
-
|
|
1053
|
-
_t2 =
|
|
1100
|
+
_context6.prev = 7;
|
|
1101
|
+
_t2 = _context6["catch"](3);
|
|
1054
1102
|
_iterator7.e(_t2);
|
|
1055
1103
|
case 8:
|
|
1056
|
-
|
|
1104
|
+
_context6.prev = 8;
|
|
1057
1105
|
_iterator7.f();
|
|
1058
|
-
return
|
|
1106
|
+
return _context6.finish(8);
|
|
1059
1107
|
case 9:
|
|
1060
1108
|
case "end":
|
|
1061
|
-
return
|
|
1109
|
+
return _context6.stop();
|
|
1062
1110
|
}
|
|
1063
|
-
},
|
|
1111
|
+
}, _callee5, this, [[3, 7, 8, 9]]);
|
|
1064
1112
|
}));
|
|
1065
|
-
function initializeNewVisibleDataSets(
|
|
1113
|
+
function initializeNewVisibleDataSets(_x7) {
|
|
1066
1114
|
return _initializeNewVisibleDataSets.apply(this, arguments);
|
|
1067
1115
|
}
|
|
1068
1116
|
return initializeNewVisibleDataSets;
|
|
@@ -1078,25 +1126,37 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1078
1126
|
}, {
|
|
1079
1127
|
key: "parseMessage",
|
|
1080
1128
|
value: function parseMessage(message, debugText) {
|
|
1081
|
-
var _message$
|
|
1082
|
-
|
|
1083
|
-
_message$locusStateEl2
|
|
1129
|
+
var _message$dataSets,
|
|
1130
|
+
_message$locusStateEl,
|
|
1131
|
+
_message$locusStateEl2,
|
|
1132
|
+
_this0 = this;
|
|
1084
1133
|
if (this.state === 'stopped') {
|
|
1085
1134
|
return [];
|
|
1086
1135
|
}
|
|
1087
1136
|
var dataSets = message.dataSets,
|
|
1088
1137
|
visibleDataSetsUrl = message.visibleDataSetsUrl;
|
|
1089
|
-
_loggerProxy.default.logger.info("HashTreeParser#parseMessage --> ".concat(this.debugId, "
|
|
1090
|
-
|
|
1138
|
+
_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) {
|
|
1139
|
+
var name = _ref5.name,
|
|
1140
|
+
version = _ref5.version;
|
|
1141
|
+
return "".concat(name, ":").concat(version);
|
|
1142
|
+
}).join(','), ", elements: ").concat((_message$locusStateEl = message.locusStateElements) === null || _message$locusStateEl === void 0 ? void 0 : _message$locusStateEl.map(function (el) {
|
|
1143
|
+
return "".concat(el.htMeta.elementId.type, ":").concat(el.htMeta.elementId.id, ":").concat(el.htMeta.elementId.version).concat(el.data ? '+' : '-');
|
|
1144
|
+
}).join(',')));
|
|
1145
|
+
if (((_message$locusStateEl2 = message.locusStateElements) === null || _message$locusStateEl2 === void 0 ? void 0 : _message$locusStateEl2.length) === 0) {
|
|
1091
1146
|
_loggerProxy.default.logger.warn("HashTreeParser#parseMessage --> ".concat(this.debugId, " got empty locusStateElements!!!"));
|
|
1092
|
-
|
|
1147
|
+
_metrics.default.sendBehavioralMetric(_constants.default.HASH_TREE_EMPTY_LOCUS_STATE_ELEMENTS, {
|
|
1148
|
+
debugId: this.debugId
|
|
1149
|
+
});
|
|
1093
1150
|
}
|
|
1094
1151
|
|
|
1095
1152
|
// first, update our metadata about the datasets with info from the message
|
|
1096
1153
|
this.visibleDataSetsUrl = visibleDataSetsUrl;
|
|
1097
1154
|
dataSets.forEach(function (dataSet) {
|
|
1098
|
-
return
|
|
1155
|
+
return _this0.updateDataSetInfo(dataSet);
|
|
1099
1156
|
});
|
|
1157
|
+
this.cancelPendingSyncsForDataSets(dataSets.map(function (ds) {
|
|
1158
|
+
return ds.name;
|
|
1159
|
+
}));
|
|
1100
1160
|
var updatedObjects = [];
|
|
1101
1161
|
|
|
1102
1162
|
// when we detect new visible datasets, it may be that the metadata about them is not
|
|
@@ -1115,9 +1175,9 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1115
1175
|
_step8;
|
|
1116
1176
|
try {
|
|
1117
1177
|
for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
|
|
1118
|
-
var
|
|
1178
|
+
var _this0$dataSets$dataS;
|
|
1119
1179
|
var dataSetName = _step8.value;
|
|
1120
|
-
var hashTree = (
|
|
1180
|
+
var hashTree = (_this0$dataSets$dataS = _this0.dataSets[dataSetName]) === null || _this0$dataSets$dataS === void 0 ? void 0 : _this0$dataSets$dataS.hashTree;
|
|
1121
1181
|
if (hashTree && object.data) {
|
|
1122
1182
|
if (hashTree.putItem(object.htMeta.elementId)) {
|
|
1123
1183
|
updatedMetadataObjects.push(object);
|
|
@@ -1139,13 +1199,13 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1139
1199
|
dataSetsRequiringInitialization = this.processVisibleDataSetChanges(removedDataSets, addedDataSets, updatedObjects);
|
|
1140
1200
|
}
|
|
1141
1201
|
}
|
|
1142
|
-
if (
|
|
1202
|
+
if (message.locusStateElements && message.locusStateElements.length > 0) {
|
|
1143
1203
|
// by this point we now have this.dataSets setup for data sets from this message
|
|
1144
1204
|
// and hash trees created for the new visible data sets,
|
|
1145
1205
|
// so we can now process all the updates from the message
|
|
1146
1206
|
dataSets.forEach(function (dataSet) {
|
|
1147
|
-
if (
|
|
1148
|
-
var hashTree =
|
|
1207
|
+
if (_this0.dataSets[dataSet.name]) {
|
|
1208
|
+
var hashTree = _this0.dataSets[dataSet.name].hashTree;
|
|
1149
1209
|
if (hashTree) {
|
|
1150
1210
|
var locusStateElementsForThisSet = message.locusStateElements.filter(function (object) {
|
|
1151
1211
|
return object.htMeta.dataSetNames.includes(dataSet.name);
|
|
@@ -1159,20 +1219,20 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1159
1219
|
item: object.htMeta.elementId
|
|
1160
1220
|
};
|
|
1161
1221
|
}));
|
|
1162
|
-
(0, _lodash.zip)(appliedChangesList, locusStateElementsForThisSet).forEach(function (
|
|
1163
|
-
var
|
|
1164
|
-
changeApplied =
|
|
1165
|
-
object =
|
|
1222
|
+
(0, _lodash.zip)(appliedChangesList, locusStateElementsForThisSet).forEach(function (_ref6) {
|
|
1223
|
+
var _ref7 = (0, _slicedToArray2.default)(_ref6, 2),
|
|
1224
|
+
changeApplied = _ref7[0],
|
|
1225
|
+
object = _ref7[1];
|
|
1166
1226
|
if (changeApplied) {
|
|
1167
1227
|
// add to updatedObjects so that our locus DTO will get updated with the new object
|
|
1168
1228
|
updatedObjects.push(object);
|
|
1169
1229
|
}
|
|
1170
1230
|
});
|
|
1171
1231
|
} else {
|
|
1172
|
-
_loggerProxy.default.logger.info("Locus-info:index#parseMessage --> ".concat(
|
|
1232
|
+
_loggerProxy.default.logger.info("Locus-info:index#parseMessage --> ".concat(_this0.debugId, " unexpected (not visible) dataSet ").concat(dataSet.name, " received in hash tree message"));
|
|
1173
1233
|
}
|
|
1174
1234
|
}
|
|
1175
|
-
|
|
1235
|
+
_this0.runSyncAlgorithm(dataSet);
|
|
1176
1236
|
});
|
|
1177
1237
|
}
|
|
1178
1238
|
if (dataSetsRequiringInitialization.length > 0) {
|
|
@@ -1198,8 +1258,8 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1198
1258
|
if (this.state === 'stopped') {
|
|
1199
1259
|
return;
|
|
1200
1260
|
}
|
|
1201
|
-
if (message.heartbeatIntervalMs) {
|
|
1202
|
-
this.
|
|
1261
|
+
if (message.heartbeatIntervalMs !== undefined) {
|
|
1262
|
+
this.topLevelHeartbeatIntervalMs = message.heartbeatIntervalMs;
|
|
1203
1263
|
}
|
|
1204
1264
|
if (this.isEndMessage(message)) {
|
|
1205
1265
|
_loggerProxy.default.logger.info("HashTreeParser#handleMessage --> ".concat(this.debugId, " received sentinel END MEETING message"));
|
|
@@ -1229,25 +1289,25 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1229
1289
|
}, {
|
|
1230
1290
|
key: "callLocusInfoUpdateCallback",
|
|
1231
1291
|
value: function callLocusInfoUpdateCallback(updates) {
|
|
1232
|
-
var
|
|
1292
|
+
var _updates$updatedObjec,
|
|
1293
|
+
_this1 = this;
|
|
1233
1294
|
if (this.state === 'stopped') {
|
|
1234
1295
|
return;
|
|
1235
1296
|
}
|
|
1236
|
-
var updateType = updates.updateType
|
|
1237
|
-
|
|
1238
|
-
if (updateType === LocusInfoUpdateType.OBJECTS_UPDATED && (updatedObjects === null || updatedObjects === void 0 ? void 0 : updatedObjects.length) > 0) {
|
|
1297
|
+
var updateType = updates.updateType;
|
|
1298
|
+
if (updateType === LocusInfoUpdateType.OBJECTS_UPDATED && ((_updates$updatedObjec = updates.updatedObjects) === null || _updates$updatedObjec === void 0 ? void 0 : _updates$updatedObjec.length) > 0) {
|
|
1239
1299
|
// Filter out updates for objects that already have a higher version in their datasets,
|
|
1240
1300
|
// or removals for objects that still exist in any of their datasets
|
|
1241
|
-
var filteredUpdates = updatedObjects.filter(function (object) {
|
|
1301
|
+
var filteredUpdates = updates.updatedObjects.filter(function (object) {
|
|
1242
1302
|
var elementId = object.htMeta.elementId;
|
|
1243
1303
|
var type = elementId.type,
|
|
1244
1304
|
id = elementId.id,
|
|
1245
1305
|
version = elementId.version;
|
|
1246
1306
|
|
|
1247
1307
|
// Check all datasets
|
|
1248
|
-
for (var _i2 = 0, _Object$keys3 = (0, _keys.default)(
|
|
1308
|
+
for (var _i2 = 0, _Object$keys3 = (0, _keys.default)(_this1.dataSets); _i2 < _Object$keys3.length; _i2++) {
|
|
1249
1309
|
var dataSetName = _Object$keys3[_i2];
|
|
1250
|
-
var dataSet =
|
|
1310
|
+
var dataSet = _this1.dataSets[dataSetName];
|
|
1251
1311
|
|
|
1252
1312
|
// only visible datasets have hash trees set
|
|
1253
1313
|
if (dataSet !== null && dataSet !== void 0 && dataSet.hashTree) {
|
|
@@ -1256,12 +1316,12 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1256
1316
|
if (object.data) {
|
|
1257
1317
|
// For updates: filter out if any dataset has a higher version
|
|
1258
1318
|
if (existingVersion > version) {
|
|
1259
|
-
_loggerProxy.default.logger.info("HashTreeParser#callLocusInfoUpdateCallback --> ".concat(
|
|
1319
|
+
_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
1320
|
return false;
|
|
1261
1321
|
}
|
|
1262
1322
|
} else if (existingVersion >= version) {
|
|
1263
1323
|
// For removals: filter out if the object still exists in any dataset
|
|
1264
|
-
_loggerProxy.default.logger.info("HashTreeParser#callLocusInfoUpdateCallback --> ".concat(
|
|
1324
|
+
_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
1325
|
return false;
|
|
1266
1326
|
}
|
|
1267
1327
|
}
|
|
@@ -1270,13 +1330,14 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1270
1330
|
return true;
|
|
1271
1331
|
});
|
|
1272
1332
|
if (filteredUpdates.length > 0) {
|
|
1273
|
-
this.locusInfoUpdateCallback(
|
|
1333
|
+
this.locusInfoUpdateCallback({
|
|
1334
|
+
updateType: updateType,
|
|
1274
1335
|
updatedObjects: filteredUpdates
|
|
1275
1336
|
});
|
|
1276
1337
|
}
|
|
1277
1338
|
} else if (updateType !== LocusInfoUpdateType.OBJECTS_UPDATED) {
|
|
1278
|
-
this.locusInfoUpdateCallback(
|
|
1279
|
-
|
|
1339
|
+
this.locusInfoUpdateCallback({
|
|
1340
|
+
updateType: updateType
|
|
1280
1341
|
});
|
|
1281
1342
|
}
|
|
1282
1343
|
}
|
|
@@ -1300,164 +1361,517 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1300
1361
|
* Performs a sync for the given data set.
|
|
1301
1362
|
*
|
|
1302
1363
|
* @param {InternalDataSet} dataSet - The data set to sync
|
|
1303
|
-
* @param {string} rootHash - Our current root hash for this data set
|
|
1304
1364
|
* @param {string} reason - The reason for the sync (used for logging)
|
|
1365
|
+
* @param {boolean} [isInitialization] - Whether this is an initialization sync (sends empty leaves data instead of comparing hashes)
|
|
1305
1366
|
* @returns {Promise<void>}
|
|
1306
1367
|
*/
|
|
1307
1368
|
}, {
|
|
1308
1369
|
key: "performSync",
|
|
1309
1370
|
value: (function () {
|
|
1310
|
-
var _performSync = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function
|
|
1311
|
-
var
|
|
1312
|
-
|
|
1313
|
-
|
|
1371
|
+
var _performSync = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee6(dataSet, reason, isInitialization) {
|
|
1372
|
+
var _dataSet$syncAbortCon;
|
|
1373
|
+
var abortController, hashTree, rootHash, leavesData, receivedHashes, hashesResult, mismatchedLeaveIndexes, syncResponse, _t3, _t4;
|
|
1374
|
+
return _regenerator.default.wrap(function (_context7) {
|
|
1375
|
+
while (1) switch (_context7.prev = _context7.next) {
|
|
1314
1376
|
case 0:
|
|
1315
1377
|
if (dataSet.hashTree) {
|
|
1316
|
-
|
|
1378
|
+
_context7.next = 1;
|
|
1317
1379
|
break;
|
|
1318
1380
|
}
|
|
1319
|
-
return
|
|
1381
|
+
return _context7.abrupt("return");
|
|
1320
1382
|
case 1:
|
|
1321
|
-
|
|
1383
|
+
abortController = (_dataSet$syncAbortCon = dataSet.syncAbortController) !== null && _dataSet$syncAbortCon !== void 0 ? _dataSet$syncAbortCon : new AbortController();
|
|
1384
|
+
dataSet.syncAbortController = abortController;
|
|
1385
|
+
hashTree = dataSet.hashTree;
|
|
1386
|
+
rootHash = hashTree.getRootHash();
|
|
1387
|
+
_context7.prev = 2;
|
|
1322
1388
|
_loggerProxy.default.logger.info("HashTreeParser#performSync --> ".concat(this.debugId, " ").concat(reason, ", syncing data set \"").concat(dataSet.name, "\""));
|
|
1323
|
-
|
|
1389
|
+
leavesData = {};
|
|
1390
|
+
if (isInitialization) {
|
|
1391
|
+
_context7.next = 10;
|
|
1392
|
+
break;
|
|
1393
|
+
}
|
|
1324
1394
|
if (!(dataSet.leafCount !== 1)) {
|
|
1325
|
-
|
|
1395
|
+
_context7.next = 9;
|
|
1326
1396
|
break;
|
|
1327
1397
|
}
|
|
1328
|
-
|
|
1329
|
-
|
|
1398
|
+
_context7.prev = 3;
|
|
1399
|
+
_context7.next = 4;
|
|
1330
1400
|
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
1401
|
case 4:
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1402
|
+
hashesResult = _context7.sent;
|
|
1403
|
+
if (hashesResult) {
|
|
1404
|
+
_context7.next = 5;
|
|
1405
|
+
break;
|
|
1406
|
+
}
|
|
1407
|
+
return _context7.abrupt("return");
|
|
1408
|
+
case 5:
|
|
1409
|
+
receivedHashes = hashesResult.hashes;
|
|
1410
|
+
this.updateDataSetLeafCount(dataSet, hashesResult.dataSet.leafCount);
|
|
1411
|
+
_context7.next = 8;
|
|
1412
|
+
break;
|
|
1413
|
+
case 6:
|
|
1414
|
+
_context7.prev = 6;
|
|
1415
|
+
_t3 = _context7["catch"](3);
|
|
1416
|
+
if (!((_t3 === null || _t3 === void 0 ? void 0 : _t3.statusCode) === 409)) {
|
|
1417
|
+
_context7.next = 7;
|
|
1344
1418
|
break;
|
|
1345
1419
|
}
|
|
1346
1420
|
// this is a leaf count mismatch, we should do nothing, just wait for another heartbeat message from Locus
|
|
1347
1421
|
_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
|
|
1422
|
+
return _context7.abrupt("return");
|
|
1423
|
+
case 7:
|
|
1350
1424
|
throw _t3;
|
|
1351
|
-
case
|
|
1425
|
+
case 8:
|
|
1352
1426
|
// identify mismatched leaves
|
|
1353
|
-
mismatchedLeaveIndexes =
|
|
1427
|
+
mismatchedLeaveIndexes = hashTree.diffHashes(receivedHashes);
|
|
1354
1428
|
mismatchedLeaveIndexes.forEach(function (index) {
|
|
1355
|
-
|
|
1429
|
+
leavesData[index] = hashTree.getLeafData(index);
|
|
1356
1430
|
});
|
|
1357
|
-
|
|
1431
|
+
_context7.next = 10;
|
|
1358
1432
|
break;
|
|
1359
|
-
case
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1433
|
+
case 9:
|
|
1434
|
+
leavesData = {
|
|
1435
|
+
0: hashTree.getLeafData(0)
|
|
1436
|
+
};
|
|
1437
|
+
case 10:
|
|
1438
|
+
if (!abortController.signal.aborted) {
|
|
1439
|
+
_context7.next = 11;
|
|
1364
1440
|
break;
|
|
1365
1441
|
}
|
|
1366
|
-
|
|
1367
|
-
return
|
|
1368
|
-
case
|
|
1369
|
-
|
|
1442
|
+
_loggerProxy.default.logger.info("HashTreeParser#performSync --> ".concat(this.debugId, " abandoning sync for \"").concat(dataSet.name, "\" before /sync - message received during sync"));
|
|
1443
|
+
return _context7.abrupt("return");
|
|
1444
|
+
case 11:
|
|
1445
|
+
// request sync for mismatched leaves
|
|
1446
|
+
syncResponse = null;
|
|
1447
|
+
if (!isInitialization) {
|
|
1448
|
+
_context7.next = 13;
|
|
1449
|
+
break;
|
|
1450
|
+
}
|
|
1451
|
+
_context7.next = 12;
|
|
1452
|
+
return this.sendSyncRequestToLocus(dataSet, {
|
|
1453
|
+
isInitialization: true
|
|
1454
|
+
});
|
|
1455
|
+
case 12:
|
|
1456
|
+
syncResponse = _context7.sent;
|
|
1457
|
+
_context7.next = 15;
|
|
1458
|
+
break;
|
|
1459
|
+
case 13:
|
|
1460
|
+
if (!((0, _keys.default)(leavesData).length > 0)) {
|
|
1461
|
+
_context7.next = 15;
|
|
1462
|
+
break;
|
|
1463
|
+
}
|
|
1464
|
+
_context7.next = 14;
|
|
1465
|
+
return this.sendSyncRequestToLocus(dataSet, {
|
|
1466
|
+
mismatchedLeavesData: leavesData
|
|
1467
|
+
});
|
|
1468
|
+
case 14:
|
|
1469
|
+
syncResponse = _context7.sent;
|
|
1470
|
+
case 15:
|
|
1370
1471
|
// sync API may return nothing (in that case data will arrive via messages)
|
|
1371
1472
|
// or it may return a response in the same format as messages
|
|
1473
|
+
// We still need to restart the sync timer as a safety net in case the messages don't arrive.
|
|
1474
|
+
this.runSyncAlgorithm(dataSet);
|
|
1372
1475
|
if (syncResponse) {
|
|
1373
|
-
|
|
1476
|
+
// clear the abort controller before processing the response so that
|
|
1477
|
+
// parseMessage() -> cancelPendingSyncsForDataSets() doesn't log a
|
|
1478
|
+
// misleading "aborting sync" message for this already-completed sync
|
|
1479
|
+
dataSet.syncAbortController = undefined;
|
|
1480
|
+
|
|
1481
|
+
// the format of sync response is the same as messages, so we can reuse the same handler
|
|
1482
|
+
this.handleMessage(syncResponse, "via sync API (".concat(isInitialization ? 'init' : "".concat((0, _keys.default)(leavesData).length, " mismatched leaves"), ")"));
|
|
1374
1483
|
}
|
|
1375
|
-
|
|
1376
|
-
_context6.next = 12;
|
|
1484
|
+
_context7.next = 17;
|
|
1377
1485
|
break;
|
|
1378
|
-
case
|
|
1379
|
-
|
|
1380
|
-
_t4 =
|
|
1381
|
-
if (_t4
|
|
1382
|
-
this.callLocusInfoUpdateCallback({
|
|
1383
|
-
updateType: LocusInfoUpdateType.MEETING_ENDED
|
|
1384
|
-
});
|
|
1385
|
-
} else {
|
|
1486
|
+
case 16:
|
|
1487
|
+
_context7.prev = 16;
|
|
1488
|
+
_t4 = _context7["catch"](2);
|
|
1489
|
+
if (!this.handleSyncErrors(_t4)) {
|
|
1386
1490
|
_loggerProxy.default.logger.warn("HashTreeParser#performSync --> ".concat(this.debugId, " error during sync for data set \"").concat(dataSet.name, "\":"), _t4);
|
|
1387
1491
|
}
|
|
1388
|
-
case
|
|
1492
|
+
case 17:
|
|
1493
|
+
_context7.prev = 17;
|
|
1494
|
+
dataSet.syncAbortController = undefined;
|
|
1495
|
+
return _context7.finish(17);
|
|
1496
|
+
case 18:
|
|
1389
1497
|
case "end":
|
|
1390
|
-
return
|
|
1498
|
+
return _context7.stop();
|
|
1391
1499
|
}
|
|
1392
|
-
},
|
|
1500
|
+
}, _callee6, this, [[2, 16, 17, 18], [3, 6]]);
|
|
1393
1501
|
}));
|
|
1394
|
-
function performSync(
|
|
1502
|
+
function performSync(_x8, _x9, _x0) {
|
|
1395
1503
|
return _performSync.apply(this, arguments);
|
|
1396
1504
|
}
|
|
1397
1505
|
return performSync;
|
|
1398
1506
|
}()
|
|
1507
|
+
/**
|
|
1508
|
+
* Cancels any pending or in-flight syncs for the specified data sets.
|
|
1509
|
+
* This removes matching entries from the sync queue and aborts any in-flight sync HTTP requests.
|
|
1510
|
+
*
|
|
1511
|
+
* @param {string[]} dataSetNames - The names of the data sets to cancel syncs for
|
|
1512
|
+
* @returns {void}
|
|
1513
|
+
*/
|
|
1514
|
+
)
|
|
1515
|
+
}, {
|
|
1516
|
+
key: "cancelPendingSyncsForDataSets",
|
|
1517
|
+
value: function cancelPendingSyncsForDataSets(dataSetNames) {
|
|
1518
|
+
var previousLength = this.syncQueue.length;
|
|
1519
|
+
this.syncQueue = this.syncQueue.filter(function (entry) {
|
|
1520
|
+
return !dataSetNames.includes(entry.dataSetName);
|
|
1521
|
+
});
|
|
1522
|
+
if (previousLength !== this.syncQueue.length) {
|
|
1523
|
+
_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(', ')));
|
|
1524
|
+
}
|
|
1525
|
+
this.markDataSetsForSyncAllBackoffSkip(dataSetNames);
|
|
1526
|
+
this.abortInFlightSyncs(dataSetNames);
|
|
1527
|
+
}
|
|
1528
|
+
|
|
1529
|
+
/**
|
|
1530
|
+
* If a syncAllDatasets backoff sleep is in progress, marks the given data sets to be skipped
|
|
1531
|
+
* after the sleep completes.
|
|
1532
|
+
*
|
|
1533
|
+
* @param {string[]} dataSetNames - The names of the data sets to mark
|
|
1534
|
+
* @returns {void}
|
|
1535
|
+
*/
|
|
1536
|
+
}, {
|
|
1537
|
+
key: "markDataSetsForSyncAllBackoffSkip",
|
|
1538
|
+
value: function markDataSetsForSyncAllBackoffSkip(dataSetNames) {
|
|
1539
|
+
if (this.syncAllBackoffType !== SyncAllBackoffType.NONE) {
|
|
1540
|
+
var _iterator9 = _createForOfIteratorHelper(dataSetNames),
|
|
1541
|
+
_step9;
|
|
1542
|
+
try {
|
|
1543
|
+
for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
|
|
1544
|
+
var name = _step9.value;
|
|
1545
|
+
this.dataSetsSyncedDuringBackoff.add(name);
|
|
1546
|
+
}
|
|
1547
|
+
} catch (err) {
|
|
1548
|
+
_iterator9.e(err);
|
|
1549
|
+
} finally {
|
|
1550
|
+
_iterator9.f();
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
}
|
|
1554
|
+
|
|
1555
|
+
/**
|
|
1556
|
+
* Aborts any in-flight sync HTTP requests for the specified data sets.
|
|
1557
|
+
*
|
|
1558
|
+
* @param {string[]} dataSetNames - The names of the data sets whose syncs should be aborted
|
|
1559
|
+
* @returns {void}
|
|
1560
|
+
*/
|
|
1561
|
+
}, {
|
|
1562
|
+
key: "abortInFlightSyncs",
|
|
1563
|
+
value: function abortInFlightSyncs(dataSetNames) {
|
|
1564
|
+
var _iterator0 = _createForOfIteratorHelper(dataSetNames),
|
|
1565
|
+
_step0;
|
|
1566
|
+
try {
|
|
1567
|
+
for (_iterator0.s(); !(_step0 = _iterator0.n()).done;) {
|
|
1568
|
+
var _this$dataSets$name;
|
|
1569
|
+
var name = _step0.value;
|
|
1570
|
+
if ((_this$dataSets$name = this.dataSets[name]) !== null && _this$dataSets$name !== void 0 && _this$dataSets$name.syncAbortController) {
|
|
1571
|
+
_loggerProxy.default.logger.info("HashTreeParser#cancelPendingSyncsForDataSets --> ".concat(this.debugId, " aborting in-flight sync for data set \"").concat(name, "\""));
|
|
1572
|
+
this.dataSets[name].syncAbortController.abort();
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1575
|
+
} catch (err) {
|
|
1576
|
+
_iterator0.e(err);
|
|
1577
|
+
} finally {
|
|
1578
|
+
_iterator0.f();
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1581
|
+
|
|
1582
|
+
/**
|
|
1583
|
+
* Enqueues a sync for the given data set. If the data set is already in the queue, the request is ignored.
|
|
1584
|
+
* This ensures that all syncs are executed sequentially and no more than 1 sync runs at a time.
|
|
1585
|
+
*
|
|
1586
|
+
* @param {string} dataSetName - The name of the data set to sync
|
|
1587
|
+
* @param {string} reason - The reason for the sync (used for logging)
|
|
1588
|
+
* @param {boolean} [isInitialization=false] - Whether this is an initialization sync (uses empty leaves data instead of hash comparison)
|
|
1589
|
+
* @returns {void}
|
|
1590
|
+
*/
|
|
1591
|
+
}, {
|
|
1592
|
+
key: "enqueueSyncForDataset",
|
|
1593
|
+
value: function enqueueSyncForDataset(dataSetName, reason) {
|
|
1594
|
+
var isInitialization = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
1595
|
+
if (this.state === 'stopped') return;
|
|
1596
|
+
var existingEntry = this.syncQueue.find(function (entry) {
|
|
1597
|
+
return entry.dataSetName === dataSetName;
|
|
1598
|
+
});
|
|
1599
|
+
if (existingEntry) {
|
|
1600
|
+
if (isInitialization) {
|
|
1601
|
+
existingEntry.isInitialization = true;
|
|
1602
|
+
}
|
|
1603
|
+
_loggerProxy.default.logger.info("HashTreeParser#enqueueSyncForDataset --> ".concat(this.debugId, " data set \"").concat(dataSetName, "\" already in sync queue, skipping"));
|
|
1604
|
+
return;
|
|
1605
|
+
}
|
|
1606
|
+
this.syncQueue.push({
|
|
1607
|
+
dataSetName: dataSetName,
|
|
1608
|
+
reason: reason,
|
|
1609
|
+
isInitialization: isInitialization
|
|
1610
|
+
});
|
|
1611
|
+
if (!this.isSyncInProgress) {
|
|
1612
|
+
this.syncQueueProcessingPromise = this.processSyncQueue();
|
|
1613
|
+
}
|
|
1614
|
+
}
|
|
1615
|
+
|
|
1616
|
+
/**
|
|
1617
|
+
* Processes the sync queue sequentially. Only one instance of this method runs at a time.
|
|
1618
|
+
*
|
|
1619
|
+
* @returns {Promise<void>}
|
|
1620
|
+
*/
|
|
1621
|
+
}, {
|
|
1622
|
+
key: "processSyncQueue",
|
|
1623
|
+
value: (function () {
|
|
1624
|
+
var _processSyncQueue = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee7() {
|
|
1625
|
+
var _ref8, dataSetName, reason, isInitialization, dataSet;
|
|
1626
|
+
return _regenerator.default.wrap(function (_context8) {
|
|
1627
|
+
while (1) switch (_context8.prev = _context8.next) {
|
|
1628
|
+
case 0:
|
|
1629
|
+
if (!this.isSyncInProgress) {
|
|
1630
|
+
_context8.next = 1;
|
|
1631
|
+
break;
|
|
1632
|
+
}
|
|
1633
|
+
return _context8.abrupt("return");
|
|
1634
|
+
case 1:
|
|
1635
|
+
this.isSyncInProgress = true;
|
|
1636
|
+
_context8.prev = 2;
|
|
1637
|
+
case 3:
|
|
1638
|
+
if (!(this.syncQueue.length > 0 && this.state !== 'stopped')) {
|
|
1639
|
+
_context8.next = 6;
|
|
1640
|
+
break;
|
|
1641
|
+
}
|
|
1642
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
1643
|
+
_ref8 = this.syncQueue.shift(), dataSetName = _ref8.dataSetName, reason = _ref8.reason, isInitialization = _ref8.isInitialization;
|
|
1644
|
+
dataSet = this.dataSets[dataSetName];
|
|
1645
|
+
if (dataSet !== null && dataSet !== void 0 && dataSet.hashTree) {
|
|
1646
|
+
_context8.next = 4;
|
|
1647
|
+
break;
|
|
1648
|
+
}
|
|
1649
|
+
return _context8.abrupt("continue", 3);
|
|
1650
|
+
case 4:
|
|
1651
|
+
_context8.next = 5;
|
|
1652
|
+
return this.performSync(dataSet, reason, isInitialization);
|
|
1653
|
+
case 5:
|
|
1654
|
+
_context8.next = 3;
|
|
1655
|
+
break;
|
|
1656
|
+
case 6:
|
|
1657
|
+
_context8.prev = 6;
|
|
1658
|
+
this.isSyncInProgress = false;
|
|
1659
|
+
return _context8.finish(6);
|
|
1660
|
+
case 7:
|
|
1661
|
+
case "end":
|
|
1662
|
+
return _context8.stop();
|
|
1663
|
+
}
|
|
1664
|
+
}, _callee7, this, [[2,, 6, 7]]);
|
|
1665
|
+
}));
|
|
1666
|
+
function processSyncQueue() {
|
|
1667
|
+
return _processSyncQueue.apply(this, arguments);
|
|
1668
|
+
}
|
|
1669
|
+
return processSyncQueue;
|
|
1670
|
+
}()
|
|
1671
|
+
/**
|
|
1672
|
+
* sets the backoff type for syncAllDatasets calls, which determines the scope of datasets that will be synced after the backoff delay.
|
|
1673
|
+
*
|
|
1674
|
+
* @param {boolean} onlyLLM - Whether the backoff is for a syncAllDatasets call that is syncing only LLM datasets
|
|
1675
|
+
* @returns {void}
|
|
1676
|
+
*/
|
|
1677
|
+
)
|
|
1678
|
+
}, {
|
|
1679
|
+
key: "setSyncAllBackoffType",
|
|
1680
|
+
value: function setSyncAllBackoffType(onlyLLM) {
|
|
1681
|
+
this.syncAllBackoffType = onlyLLM ? SyncAllBackoffType.ONLY_LLM : SyncAllBackoffType.ALL;
|
|
1682
|
+
}
|
|
1683
|
+
|
|
1684
|
+
/**
|
|
1685
|
+
* Checks if a syncAll backoff is already in progress. If so, upgrades the scope from
|
|
1686
|
+
* onlyLLM to all datasets when the new call has a broader scope.
|
|
1687
|
+
*
|
|
1688
|
+
* @param {boolean} onlyLLM - Whether the current call is for LLM datasets only
|
|
1689
|
+
* @returns {boolean} true if a backoff is already pending (caller should return early)
|
|
1690
|
+
*/
|
|
1691
|
+
}, {
|
|
1692
|
+
key: "tryUpgradePendingBackoff",
|
|
1693
|
+
value: function tryUpgradePendingBackoff(onlyLLM) {
|
|
1694
|
+
if (this.syncAllBackoffType !== SyncAllBackoffType.NONE) {
|
|
1695
|
+
if (!onlyLLM && this.syncAllBackoffType === SyncAllBackoffType.ONLY_LLM) {
|
|
1696
|
+
this.setSyncAllBackoffType(false);
|
|
1697
|
+
_loggerProxy.default.logger.info("HashTreeParser#syncAllDatasets --> ".concat(this.debugId, " upgraded pending syncAll from onlyLLM to all datasets"));
|
|
1698
|
+
}
|
|
1699
|
+
return true;
|
|
1700
|
+
}
|
|
1701
|
+
return false;
|
|
1702
|
+
}
|
|
1703
|
+
|
|
1704
|
+
/**
|
|
1705
|
+
* Syncs all data sets that have hash trees, one by one in sequence, using the priority order
|
|
1706
|
+
* provided by sortByInitPriority().
|
|
1707
|
+
*
|
|
1708
|
+
* If a call is already waiting in the backoff delay phase, a new call with a broader scope
|
|
1709
|
+
* (onlyLLM=false) will upgrade the pending scope, and the dataset list will be computed after
|
|
1710
|
+
* the backoff using the upgraded scope. After the backoff, the sync queue handles deduplication
|
|
1711
|
+
* so no guard is needed.
|
|
1712
|
+
*
|
|
1713
|
+
* @param {Object} [options={}] - Options for syncing
|
|
1714
|
+
* @param {boolean} [options.onlyLLM=false] - Whether to sync only LLM based data sets
|
|
1715
|
+
* @returns {Promise<void>}
|
|
1716
|
+
*/
|
|
1717
|
+
}, {
|
|
1718
|
+
key: "syncAllDatasets",
|
|
1719
|
+
value: (function () {
|
|
1720
|
+
var _syncAllDatasets = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee8() {
|
|
1721
|
+
var options,
|
|
1722
|
+
_options$onlyLLM,
|
|
1723
|
+
onlyLLM,
|
|
1724
|
+
dataSetsToSync,
|
|
1725
|
+
delay,
|
|
1726
|
+
effectiveBackoffType,
|
|
1727
|
+
skippedDataSets,
|
|
1728
|
+
effectiveDataSetsToSync,
|
|
1729
|
+
_iterator1,
|
|
1730
|
+
_step1,
|
|
1731
|
+
ds,
|
|
1732
|
+
_args9 = arguments;
|
|
1733
|
+
return _regenerator.default.wrap(function (_context9) {
|
|
1734
|
+
while (1) switch (_context9.prev = _context9.next) {
|
|
1735
|
+
case 0:
|
|
1736
|
+
options = _args9.length > 0 && _args9[0] !== undefined ? _args9[0] : {};
|
|
1737
|
+
_options$onlyLLM = options.onlyLLM, onlyLLM = _options$onlyLLM === void 0 ? false : _options$onlyLLM;
|
|
1738
|
+
if (!(this.state === 'stopped')) {
|
|
1739
|
+
_context9.next = 1;
|
|
1740
|
+
break;
|
|
1741
|
+
}
|
|
1742
|
+
return _context9.abrupt("return");
|
|
1743
|
+
case 1:
|
|
1744
|
+
if (!this.tryUpgradePendingBackoff(onlyLLM)) {
|
|
1745
|
+
_context9.next = 2;
|
|
1746
|
+
break;
|
|
1747
|
+
}
|
|
1748
|
+
return _context9.abrupt("return");
|
|
1749
|
+
case 2:
|
|
1750
|
+
dataSetsToSync = this.getSortedDataSetsWithHashTrees(onlyLLM);
|
|
1751
|
+
if (!(dataSetsToSync.length === 0)) {
|
|
1752
|
+
_context9.next = 3;
|
|
1753
|
+
break;
|
|
1754
|
+
}
|
|
1755
|
+
return _context9.abrupt("return");
|
|
1756
|
+
case 3:
|
|
1757
|
+
this.setSyncAllBackoffType(onlyLLM);
|
|
1758
|
+
delay = this.getWeightedBackoffTime(dataSetsToSync[0].backoff);
|
|
1759
|
+
_loggerProxy.default.logger.info("HashTreeParser#syncAllDatasets --> ".concat(this.debugId, " starting backoff delay of ").concat(delay, "ms (onlyLLM=").concat(onlyLLM, ")"));
|
|
1760
|
+
|
|
1761
|
+
// delay the start of the syncs - this is a Locus requirement to avoid thundering herd issues
|
|
1762
|
+
_context9.next = 4;
|
|
1763
|
+
return (0, _utils.sleep)(delay);
|
|
1764
|
+
case 4:
|
|
1765
|
+
// read the (possibly upgraded) scope and clear the backoff flag
|
|
1766
|
+
effectiveBackoffType = this.syncAllBackoffType;
|
|
1767
|
+
skippedDataSets = this.dataSetsSyncedDuringBackoff;
|
|
1768
|
+
this.syncAllBackoffType = SyncAllBackoffType.NONE;
|
|
1769
|
+
this.dataSetsSyncedDuringBackoff = new _set.default();
|
|
1770
|
+
if (!(this.state === 'stopped')) {
|
|
1771
|
+
_context9.next = 5;
|
|
1772
|
+
break;
|
|
1773
|
+
}
|
|
1774
|
+
return _context9.abrupt("return");
|
|
1775
|
+
case 5:
|
|
1776
|
+
// re-evaluate the dataset list after the sleep, since the scope may have been upgraded
|
|
1777
|
+
// and exclude datasets that received messages during the backoff sleep
|
|
1778
|
+
effectiveDataSetsToSync = this.getSortedDataSetsWithHashTrees(effectiveBackoffType === SyncAllBackoffType.ONLY_LLM).filter(function (ds) {
|
|
1779
|
+
return !skippedDataSets.has(ds.name);
|
|
1780
|
+
});
|
|
1781
|
+
if (skippedDataSets.size > 0) {
|
|
1782
|
+
_loggerProxy.default.logger.info("HashTreeParser#syncAllDatasets --> ".concat(this.debugId, " skipping datasets that received messages during backoff: ").concat((0, _toConsumableArray2.default)(skippedDataSets).join(', ')));
|
|
1783
|
+
}
|
|
1784
|
+
_loggerProxy.default.logger.info("HashTreeParser#syncAllDatasets --> ".concat(this.debugId, " syncing ").concat(effectiveBackoffType === SyncAllBackoffType.ONLY_LLM ? 'only LLM' : 'all', " datasets: ").concat(effectiveDataSetsToSync.map(function (ds) {
|
|
1785
|
+
return ds.name;
|
|
1786
|
+
}).join(', ')));
|
|
1787
|
+
_iterator1 = _createForOfIteratorHelper(effectiveDataSetsToSync);
|
|
1788
|
+
try {
|
|
1789
|
+
for (_iterator1.s(); !(_step1 = _iterator1.n()).done;) {
|
|
1790
|
+
ds = _step1.value;
|
|
1791
|
+
this.enqueueSyncForDataset(ds.name, 'syncAllDatasets');
|
|
1792
|
+
}
|
|
1793
|
+
} catch (err) {
|
|
1794
|
+
_iterator1.e(err);
|
|
1795
|
+
} finally {
|
|
1796
|
+
_iterator1.f();
|
|
1797
|
+
}
|
|
1798
|
+
_context9.next = 6;
|
|
1799
|
+
return this.syncQueueProcessingPromise;
|
|
1800
|
+
case 6:
|
|
1801
|
+
case "end":
|
|
1802
|
+
return _context9.stop();
|
|
1803
|
+
}
|
|
1804
|
+
}, _callee8, this);
|
|
1805
|
+
}));
|
|
1806
|
+
function syncAllDatasets() {
|
|
1807
|
+
return _syncAllDatasets.apply(this, arguments);
|
|
1808
|
+
}
|
|
1809
|
+
return syncAllDatasets;
|
|
1810
|
+
}()
|
|
1811
|
+
/**
|
|
1812
|
+
* Returns the list of data sets that have hash trees, sorted by the priority order provided by sortByInitPriority().
|
|
1813
|
+
*
|
|
1814
|
+
* @param {boolean} onlyLLM - Whether to include only LLM based data sets
|
|
1815
|
+
* @returns {Array<{name: string, backoff: {maxMs: number, exponent: number}}>} The sorted list of data sets with their backoff configurations
|
|
1816
|
+
*/
|
|
1817
|
+
)
|
|
1818
|
+
}, {
|
|
1819
|
+
key: "getSortedDataSetsWithHashTrees",
|
|
1820
|
+
value: function getSortedDataSetsWithHashTrees(onlyLLM) {
|
|
1821
|
+
var dataSets = (0, _values.default)(this.dataSets).filter(function (dataSet) {
|
|
1822
|
+
return dataSet === null || dataSet === void 0 ? void 0 : dataSet.hashTree;
|
|
1823
|
+
}).map(function (dataSet) {
|
|
1824
|
+
return {
|
|
1825
|
+
name: dataSet.name,
|
|
1826
|
+
backoff: dataSet.backoff
|
|
1827
|
+
};
|
|
1828
|
+
});
|
|
1829
|
+
if (onlyLLM) {
|
|
1830
|
+
dataSets = dataSets.filter(function (ds) {
|
|
1831
|
+
return _constants3.LLM_DATASET_NAMES.includes(ds.name);
|
|
1832
|
+
});
|
|
1833
|
+
}
|
|
1834
|
+
return (0, _utils.sortByInitPriority)(dataSets, _constants3.DATA_SET_INIT_PRIORITY);
|
|
1835
|
+
}
|
|
1836
|
+
|
|
1399
1837
|
/**
|
|
1400
1838
|
* Runs the sync algorithm for the given data set.
|
|
1401
1839
|
*
|
|
1402
1840
|
* @param {DataSet} receivedDataSet - The data set to run the sync algorithm for.
|
|
1403
1841
|
* @returns {void}
|
|
1404
1842
|
*/
|
|
1405
|
-
)
|
|
1406
1843
|
}, {
|
|
1407
1844
|
key: "runSyncAlgorithm",
|
|
1408
1845
|
value: function runSyncAlgorithm(receivedDataSet) {
|
|
1409
|
-
var
|
|
1846
|
+
var _this10 = this;
|
|
1410
1847
|
var dataSet = this.dataSets[receivedDataSet.name];
|
|
1411
1848
|
if (!dataSet) {
|
|
1412
1849
|
_loggerProxy.default.logger.warn("HashTreeParser#runSyncAlgorithm --> ".concat(this.debugId, " No data set found for ").concat(receivedDataSet.name, ", skipping sync algorithm"));
|
|
1413
1850
|
return;
|
|
1414
1851
|
}
|
|
1415
1852
|
if (!dataSet.hashTree) {
|
|
1416
|
-
|
|
1853
|
+
// no hash tree, so no need to do any syncing
|
|
1854
|
+
// we fall into this branch often, because Locus sends dataSets in messages that are not visible to us
|
|
1855
|
+
|
|
1417
1856
|
return;
|
|
1418
1857
|
}
|
|
1419
1858
|
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
1859
|
var delay = dataSet.idleMs + this.getWeightedBackoffTime(dataSet.backoff);
|
|
1425
1860
|
if (delay > 0) {
|
|
1426
1861
|
if (dataSet.timer) {
|
|
1427
1862
|
clearTimeout(dataSet.timer);
|
|
1428
1863
|
}
|
|
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);
|
|
1864
|
+
dataSet.timer = setTimeout(function () {
|
|
1865
|
+
dataSet.timer = undefined;
|
|
1866
|
+
if (!dataSet.hashTree) {
|
|
1867
|
+
_loggerProxy.default.logger.warn("HashTreeParser#runSyncAlgorithm --> ".concat(_this10.debugId, " Data set \"").concat(dataSet.name, "\" no longer has a hash tree, cannot run sync algorithm"));
|
|
1868
|
+
return;
|
|
1869
|
+
}
|
|
1870
|
+
var rootHash = dataSet.hashTree.getRootHash();
|
|
1871
|
+
if (dataSet.root !== rootHash) {
|
|
1872
|
+
_this10.enqueueSyncForDataset(dataSet.name, "Root hash mismatch: received=".concat(dataSet.root, ", ours=").concat(rootHash));
|
|
1873
|
+
}
|
|
1874
|
+
}, delay);
|
|
1461
1875
|
} else {
|
|
1462
1876
|
_loggerProxy.default.logger.info("HashTreeParser#runSyncAlgorithm --> ".concat(this.debugId, " No delay for \"").concat(dataSet.name, "\" data set, skipping sync timer reset/setup"));
|
|
1463
1877
|
}
|
|
@@ -1475,48 +1889,45 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1475
1889
|
}, {
|
|
1476
1890
|
key: "resetHeartbeatWatchdogs",
|
|
1477
1891
|
value: function resetHeartbeatWatchdogs(receivedDataSets) {
|
|
1478
|
-
var
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
}
|
|
1482
|
-
var _iterator9 = _createForOfIteratorHelper(receivedDataSets),
|
|
1483
|
-
_step9;
|
|
1892
|
+
var _this11 = this;
|
|
1893
|
+
var _iterator10 = _createForOfIteratorHelper(receivedDataSets),
|
|
1894
|
+
_step10;
|
|
1484
1895
|
try {
|
|
1485
1896
|
var _loop2 = function _loop2() {
|
|
1486
|
-
var
|
|
1487
|
-
var
|
|
1488
|
-
|
|
1489
|
-
// eslint-disable-next-line no-continue
|
|
1490
|
-
return 1; // continue
|
|
1491
|
-
}
|
|
1897
|
+
var _dataSet$heartbeatInt;
|
|
1898
|
+
var receivedDataSet = _step10.value;
|
|
1899
|
+
var dataSet = _this11.dataSets[receivedDataSet.name];
|
|
1492
1900
|
if (dataSet.heartbeatWatchdogTimer) {
|
|
1493
1901
|
clearTimeout(dataSet.heartbeatWatchdogTimer);
|
|
1494
1902
|
dataSet.heartbeatWatchdogTimer = undefined;
|
|
1495
1903
|
}
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1904
|
+
|
|
1905
|
+
// dataset-level heartbeatIntervalMs takes priority; fall back to top-level common value
|
|
1906
|
+
var heartbeatIntervalMs = (_dataSet$heartbeatInt = dataSet === null || dataSet === void 0 ? void 0 : dataSet.heartbeatIntervalMs) !== null && _dataSet$heartbeatInt !== void 0 ? _dataSet$heartbeatInt : _this11.topLevelHeartbeatIntervalMs;
|
|
1907
|
+
if (!(dataSet !== null && dataSet !== void 0 && dataSet.hashTree) || !heartbeatIntervalMs) {
|
|
1908
|
+
// eslint-disable-next-line no-continue
|
|
1909
|
+
return 1; // continue
|
|
1910
|
+
}
|
|
1911
|
+
var backoffTime = _this11.getWeightedBackoffTime(dataSet.backoff);
|
|
1912
|
+
var delay = heartbeatIntervalMs + backoffTime;
|
|
1913
|
+
dataSet.heartbeatWatchdogTimer = setTimeout(function () {
|
|
1914
|
+
dataSet.heartbeatWatchdogTimer = undefined;
|
|
1915
|
+
_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"));
|
|
1916
|
+
_metrics.default.sendBehavioralMetric(_constants.default.HASH_TREE_HEARTBEAT_WATCHDOG_EXPIRED, {
|
|
1917
|
+
debugId: _this11.debugId,
|
|
1918
|
+
dataSetName: dataSet.name
|
|
1919
|
+
});
|
|
1920
|
+
_this11.enqueueSyncForDataset(dataSet.name, "heartbeat watchdog expired");
|
|
1921
|
+
_this11.resetHeartbeatWatchdogs([dataSet]);
|
|
1922
|
+
}, delay);
|
|
1512
1923
|
};
|
|
1513
|
-
for (
|
|
1924
|
+
for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {
|
|
1514
1925
|
if (_loop2()) continue;
|
|
1515
1926
|
}
|
|
1516
1927
|
} catch (err) {
|
|
1517
|
-
|
|
1928
|
+
_iterator10.e(err);
|
|
1518
1929
|
} finally {
|
|
1519
|
-
|
|
1930
|
+
_iterator10.f();
|
|
1520
1931
|
}
|
|
1521
1932
|
}
|
|
1522
1933
|
|
|
@@ -1550,7 +1961,14 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1550
1961
|
value: function stop() {
|
|
1551
1962
|
_loggerProxy.default.logger.info("HashTreeParser#stop --> ".concat(this.debugId, " Stopping HashTreeParser, clearing timers and hash trees"));
|
|
1552
1963
|
this.stopAllTimers();
|
|
1964
|
+
this.syncQueue = [];
|
|
1965
|
+
this.topLevelHeartbeatIntervalMs = undefined;
|
|
1966
|
+
this.syncAllBackoffType = SyncAllBackoffType.NONE;
|
|
1967
|
+
this.dataSetsSyncedDuringBackoff = new _set.default();
|
|
1553
1968
|
(0, _values.default)(this.dataSets).forEach(function (dataSet) {
|
|
1969
|
+
var _dataSet$syncAbortCon2;
|
|
1970
|
+
(_dataSet$syncAbortCon2 = dataSet.syncAbortController) === null || _dataSet$syncAbortCon2 === void 0 ? void 0 : _dataSet$syncAbortCon2.abort();
|
|
1971
|
+
dataSet.syncAbortController = undefined;
|
|
1554
1972
|
dataSet.hashTree = undefined;
|
|
1555
1973
|
});
|
|
1556
1974
|
this.visibleDataSets = [];
|
|
@@ -1558,29 +1976,41 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1558
1976
|
}
|
|
1559
1977
|
|
|
1560
1978
|
/**
|
|
1561
|
-
*
|
|
1979
|
+
* Cleans up the HashTreeParser, stopping all timers and clearing all internal state.
|
|
1980
|
+
* After calling this, the parser should not be used anymore.
|
|
1981
|
+
* @returns {void}
|
|
1982
|
+
*/
|
|
1983
|
+
}, {
|
|
1984
|
+
key: "cleanUp",
|
|
1985
|
+
value: function cleanUp() {
|
|
1986
|
+
this.stop();
|
|
1987
|
+
this.dataSets = {};
|
|
1988
|
+
}
|
|
1989
|
+
|
|
1990
|
+
/**
|
|
1991
|
+
* Resumes the HashTreeParser that was previously stopped, using a hash tree message.
|
|
1562
1992
|
* @param {HashTreeMessage} message - The message to resume with, it must contain metadata with visible data sets info
|
|
1563
1993
|
* @returns {void}
|
|
1564
1994
|
*/
|
|
1565
1995
|
}, {
|
|
1566
|
-
key: "
|
|
1567
|
-
value: function
|
|
1996
|
+
key: "resumeFromMessage",
|
|
1997
|
+
value: function resumeFromMessage(message) {
|
|
1568
1998
|
var _message$locusStateEl3, _metadataObject$data;
|
|
1569
1999
|
// check that message contains metadata with visible data sets - this is essential to be able to resume
|
|
1570
2000
|
var metadataObject = (_message$locusStateEl3 = message.locusStateElements) === null || _message$locusStateEl3 === void 0 ? void 0 : _message$locusStateEl3.find(function (el) {
|
|
1571
2001
|
return (0, _utils.isMetadata)(el);
|
|
1572
2002
|
});
|
|
1573
2003
|
if (!(metadataObject !== null && metadataObject !== void 0 && (_metadataObject$data = metadataObject.data) !== null && _metadataObject$data !== void 0 && _metadataObject$data.visibleDataSets)) {
|
|
1574
|
-
_loggerProxy.default.logger.warn("HashTreeParser#
|
|
2004
|
+
_loggerProxy.default.logger.warn("HashTreeParser#resumeFromMessage --> ".concat(this.debugId, " Cannot resume HashTreeParser because the message is missing metadata with visible data sets info"));
|
|
1575
2005
|
return;
|
|
1576
2006
|
}
|
|
1577
2007
|
this.setVisibleDataSets(metadataObject.data.visibleDataSets, message.dataSets);
|
|
1578
2008
|
this.dataSets = {};
|
|
1579
|
-
var
|
|
1580
|
-
|
|
2009
|
+
var _iterator11 = _createForOfIteratorHelper(message.dataSets),
|
|
2010
|
+
_step11;
|
|
1581
2011
|
try {
|
|
1582
|
-
for (
|
|
1583
|
-
var dataSet =
|
|
2012
|
+
for (_iterator11.s(); !(_step11 = _iterator11.n()).done;) {
|
|
2013
|
+
var dataSet = _step11.value;
|
|
1584
2014
|
var name = dataSet.name,
|
|
1585
2015
|
leafCount = dataSet.leafCount;
|
|
1586
2016
|
this.dataSets[name] = _objectSpread(_objectSpread({}, dataSet), {}, {
|
|
@@ -1588,23 +2018,62 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1588
2018
|
});
|
|
1589
2019
|
}
|
|
1590
2020
|
} catch (err) {
|
|
1591
|
-
|
|
2021
|
+
_iterator11.e(err);
|
|
1592
2022
|
} finally {
|
|
1593
|
-
|
|
2023
|
+
_iterator11.f();
|
|
1594
2024
|
}
|
|
1595
|
-
_loggerProxy.default.logger.info("HashTreeParser#
|
|
2025
|
+
_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
2026
|
return ds.name;
|
|
1597
2027
|
}).join(', ')));
|
|
1598
2028
|
this.state = 'active';
|
|
1599
2029
|
this.handleMessage(message, 'on resume');
|
|
1600
2030
|
}
|
|
2031
|
+
|
|
2032
|
+
/**
|
|
2033
|
+
* Resumes the HashTreeParser that was previously stopped, using a Locus API response.
|
|
2034
|
+
* Unlike resumeFromMessage(), this does not require metadata/dataSets in the input,
|
|
2035
|
+
* as it fetches all necessary information from Locus via initializeFromGetLociResponse.
|
|
2036
|
+
* @param {LocusDTO} locus - locus object from an API response
|
|
2037
|
+
* @returns {Promise}
|
|
2038
|
+
*/
|
|
2039
|
+
}, {
|
|
2040
|
+
key: "resumeFromApiResponse",
|
|
2041
|
+
value: (function () {
|
|
2042
|
+
var _resumeFromApiResponse = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee9(locus) {
|
|
2043
|
+
return _regenerator.default.wrap(function (_context0) {
|
|
2044
|
+
while (1) switch (_context0.prev = _context0.next) {
|
|
2045
|
+
case 0:
|
|
2046
|
+
this.state = 'active';
|
|
2047
|
+
this.dataSets = {};
|
|
2048
|
+
_loggerProxy.default.logger.info("HashTreeParser#resumeFromApiResponse --> ".concat(this.debugId, " Resuming HashTreeParser from API response"));
|
|
2049
|
+
_context0.next = 1;
|
|
2050
|
+
return this.initializeFromGetLociResponse(locus);
|
|
2051
|
+
case 1:
|
|
2052
|
+
case "end":
|
|
2053
|
+
return _context0.stop();
|
|
2054
|
+
}
|
|
2055
|
+
}, _callee9, this);
|
|
2056
|
+
}));
|
|
2057
|
+
function resumeFromApiResponse(_x1) {
|
|
2058
|
+
return _resumeFromApiResponse.apply(this, arguments);
|
|
2059
|
+
}
|
|
2060
|
+
return resumeFromApiResponse;
|
|
2061
|
+
}())
|
|
1601
2062
|
}, {
|
|
1602
2063
|
key: "checkForSentinelHttpResponse",
|
|
1603
2064
|
value: function checkForSentinelHttpResponse(error, dataSetName) {
|
|
1604
2065
|
var _error$body;
|
|
2066
|
+
// 404 for any dataset means the locus is no longer available at this URL - could be replaced or ended
|
|
2067
|
+
// if a dataset is just not visible, we would get a 400
|
|
2068
|
+
if (error.statusCode === 404) {
|
|
2069
|
+
_loggerProxy.default.logger.info("HashTreeParser#checkForSentinelHttpResponse --> ".concat(this.debugId, " Received 404 for data set \"").concat(dataSetName, "\", locus not found"));
|
|
2070
|
+
this.stopAllTimers();
|
|
2071
|
+
throw new LocusNotFoundError();
|
|
2072
|
+
}
|
|
1605
2073
|
var isValidDataSetForSentinel = dataSetName === undefined || PossibleSentinelMessageDataSetNames.includes(dataSetName.toLowerCase());
|
|
1606
|
-
if (
|
|
1607
|
-
|
|
2074
|
+
if (error.statusCode === 409 && ((_error$body = error.body) === null || _error$body === void 0 ? void 0 : _error$body.errorCode) === _types2.LocusErrorCodes.LOCUS_INACTIVE && isValidDataSetForSentinel) {
|
|
2075
|
+
var _error$body2;
|
|
2076
|
+
_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
2077
|
this.stopAllTimers();
|
|
1609
2078
|
throw new MeetingEndedError();
|
|
1610
2079
|
}
|
|
@@ -1614,37 +2083,49 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1614
2083
|
* Gets the current hashes from the locus for a specific data set.
|
|
1615
2084
|
* @param {string} dataSetName
|
|
1616
2085
|
* @param {string} currentRootHash
|
|
1617
|
-
* @returns {
|
|
2086
|
+
* @returns {Object|null} An object containing the hashes and leaf count, or null if the hashes match and no sync is needed
|
|
1618
2087
|
*/
|
|
1619
2088
|
}, {
|
|
1620
2089
|
key: "getHashesFromLocus",
|
|
1621
2090
|
value: function getHashesFromLocus(dataSetName, currentRootHash) {
|
|
1622
|
-
var
|
|
2091
|
+
var _this12 = this;
|
|
1623
2092
|
_loggerProxy.default.logger.info("HashTreeParser#getHashesFromLocus --> ".concat(this.debugId, " Requesting hashes for data set \"").concat(dataSetName, "\""));
|
|
1624
2093
|
var dataSet = this.dataSets[dataSetName];
|
|
1625
2094
|
var url = "".concat(dataSet.url, "/hashtree");
|
|
1626
2095
|
return this.webexRequest({
|
|
1627
|
-
method:
|
|
2096
|
+
method: _constants2.HTTP_VERBS.GET,
|
|
1628
2097
|
uri: url,
|
|
1629
2098
|
qs: {
|
|
1630
2099
|
rootHash: currentRootHash
|
|
1631
2100
|
}
|
|
1632
2101
|
}).then(function (response) {
|
|
1633
2102
|
var _response$body, _response$body2;
|
|
2103
|
+
if (!response.body || (0, _lodash.isEmpty)(response.body)) {
|
|
2104
|
+
// 204 with empty body means our hashes match Locus, no sync needed
|
|
2105
|
+
_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"));
|
|
2106
|
+
return null;
|
|
2107
|
+
}
|
|
1634
2108
|
var hashes = (_response$body = response.body) === null || _response$body === void 0 ? void 0 : _response$body.hashes;
|
|
1635
2109
|
var dataSetFromResponse = (_response$body2 = response.body) === null || _response$body2 === void 0 ? void 0 : _response$body2.dataSet;
|
|
1636
2110
|
if (!hashes || !(0, _isArray.default)(hashes)) {
|
|
1637
|
-
_loggerProxy.default.logger.warn("HashTreeParser#getHashesFromLocus --> ".concat(
|
|
2111
|
+
_loggerProxy.default.logger.warn("HashTreeParser#getHashesFromLocus --> ".concat(_this12.debugId, " Locus returned invalid hashes, response body="), response.body);
|
|
1638
2112
|
throw new Error("Locus returned invalid hashes: ".concat(hashes));
|
|
1639
2113
|
}
|
|
1640
|
-
_loggerProxy.default.logger.info("HashTreeParser#getHashesFromLocus --> ".concat(
|
|
2114
|
+
_loggerProxy.default.logger.info("HashTreeParser#getHashesFromLocus --> ".concat(_this12.debugId, " Received hashes for data set \"").concat(dataSetName, "\": ").concat((0, _stringify.default)(hashes)));
|
|
1641
2115
|
return {
|
|
1642
2116
|
hashes: hashes,
|
|
1643
2117
|
dataSet: dataSetFromResponse
|
|
1644
2118
|
};
|
|
1645
2119
|
}).catch(function (error) {
|
|
1646
|
-
_loggerProxy.default.logger.error("HashTreeParser#getHashesFromLocus --> ".concat(
|
|
1647
|
-
|
|
2120
|
+
_loggerProxy.default.logger.error("HashTreeParser#getHashesFromLocus --> ".concat(_this12.debugId, " Error ").concat(error.statusCode, " fetching hashes for data set \"").concat(dataSetName, "\":"), error);
|
|
2121
|
+
_this12.checkForSentinelHttpResponse(error, dataSet.name);
|
|
2122
|
+
_metrics.default.sendBehavioralMetric(_constants.default.HASH_TREE_SYNC_FAILURE, {
|
|
2123
|
+
debugId: _this12.debugId,
|
|
2124
|
+
dataSetName: dataSetName,
|
|
2125
|
+
request: 'GET /hashtree',
|
|
2126
|
+
statusCode: error.statusCode,
|
|
2127
|
+
reason: error.message
|
|
2128
|
+
});
|
|
1648
2129
|
throw error;
|
|
1649
2130
|
});
|
|
1650
2131
|
}
|
|
@@ -1653,43 +2134,60 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1653
2134
|
* Sends a sync request to Locus for the specified data set.
|
|
1654
2135
|
*
|
|
1655
2136
|
* @param {InternalDataSet} dataSet The data set to sync.
|
|
1656
|
-
* @param {
|
|
2137
|
+
* @param {Object} options Either `{ isInitialization: true }` for init syncs (uses leafCount=1 with empty leaf data) or `{ mismatchedLeavesData }` for normal syncs.
|
|
1657
2138
|
* @returns {Promise<HashTreeMessage|null>}
|
|
1658
2139
|
*/
|
|
1659
2140
|
}, {
|
|
1660
2141
|
key: "sendSyncRequestToLocus",
|
|
1661
|
-
value: function sendSyncRequestToLocus(dataSet,
|
|
1662
|
-
var
|
|
2142
|
+
value: function sendSyncRequestToLocus(dataSet, options) {
|
|
2143
|
+
var _this13 = this;
|
|
1663
2144
|
_loggerProxy.default.logger.info("HashTreeParser#sendSyncRequestToLocus --> ".concat(this.debugId, " Sending sync request for data set \"").concat(dataSet.name, "\""));
|
|
2145
|
+
var isInitialization = 'isInitialization' in options;
|
|
1664
2146
|
var url = "".concat(dataSet.url, "/sync");
|
|
1665
2147
|
var body = {
|
|
1666
|
-
leafCount: dataSet.leafCount,
|
|
2148
|
+
leafCount: isInitialization ? 1 : dataSet.leafCount,
|
|
1667
2149
|
leafDataEntries: []
|
|
1668
2150
|
};
|
|
1669
|
-
|
|
2151
|
+
if (isInitialization) {
|
|
2152
|
+
// initialization sync: Locus requires leafCount=1 with a single empty leaf
|
|
1670
2153
|
body.leafDataEntries.push({
|
|
1671
|
-
leafIndex:
|
|
1672
|
-
elementIds:
|
|
2154
|
+
leafIndex: 0,
|
|
2155
|
+
elementIds: []
|
|
1673
2156
|
});
|
|
1674
|
-
}
|
|
1675
|
-
|
|
2157
|
+
} else {
|
|
2158
|
+
var mismatchedLeavesData = options.mismatchedLeavesData;
|
|
2159
|
+
(0, _keys.default)(mismatchedLeavesData).forEach(function (index) {
|
|
2160
|
+
var leafIndex = (0, _parseInt2.default)(index, 10);
|
|
2161
|
+
body.leafDataEntries.push({
|
|
2162
|
+
leafIndex: leafIndex,
|
|
2163
|
+
elementIds: mismatchedLeavesData[leafIndex]
|
|
2164
|
+
});
|
|
2165
|
+
});
|
|
2166
|
+
}
|
|
2167
|
+
var ourCurrentRootHash = dataSet.hashTree ? dataSet.hashTree.getRootHash() : _constants3.EMPTY_HASH;
|
|
1676
2168
|
return this.webexRequest({
|
|
1677
|
-
method:
|
|
2169
|
+
method: _constants2.HTTP_VERBS.POST,
|
|
1678
2170
|
uri: url,
|
|
1679
2171
|
qs: {
|
|
1680
2172
|
rootHash: ourCurrentRootHash
|
|
1681
2173
|
},
|
|
1682
2174
|
body: body
|
|
1683
2175
|
}).then(function (resp) {
|
|
1684
|
-
_loggerProxy.default.logger.info("HashTreeParser#sendSyncRequestToLocus --> ".concat(_this14.debugId, " Sync request succeeded for \"").concat(dataSet.name, "\""));
|
|
1685
2176
|
if (!resp.body || (0, _lodash.isEmpty)(resp.body)) {
|
|
1686
|
-
_loggerProxy.default.logger.info("HashTreeParser#sendSyncRequestToLocus --> ".concat(
|
|
2177
|
+
_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
2178
|
return null;
|
|
1688
2179
|
}
|
|
1689
2180
|
return resp.body;
|
|
1690
2181
|
}).catch(function (error) {
|
|
1691
|
-
_loggerProxy.default.logger.error("HashTreeParser#sendSyncRequestToLocus --> ".concat(
|
|
1692
|
-
|
|
2182
|
+
_loggerProxy.default.logger.error("HashTreeParser#sendSyncRequestToLocus --> ".concat(_this13.debugId, " Error ").concat(error.statusCode, " sending sync request for data set \"").concat(dataSet.name, "\":"), error);
|
|
2183
|
+
_this13.checkForSentinelHttpResponse(error, dataSet.name);
|
|
2184
|
+
_metrics.default.sendBehavioralMetric(_constants.default.HASH_TREE_SYNC_FAILURE, {
|
|
2185
|
+
debugId: _this13.debugId,
|
|
2186
|
+
dataSetName: dataSet.name,
|
|
2187
|
+
request: 'POST /sync',
|
|
2188
|
+
statusCode: error.statusCode,
|
|
2189
|
+
reason: error.message
|
|
2190
|
+
});
|
|
1693
2191
|
throw error;
|
|
1694
2192
|
});
|
|
1695
2193
|
}
|