@webex/plugin-meetings 3.11.0-next.4 → 3.11.0-next.40
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/dist/aiEnableRequest/index.js +184 -0
- package/dist/aiEnableRequest/index.js.map +1 -0
- package/dist/aiEnableRequest/utils.js +36 -0
- package/dist/aiEnableRequest/utils.js.map +1 -0
- package/dist/annotation/index.js +3 -3
- package/dist/annotation/index.js.map +1 -1
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/config.js +5 -1
- package/dist/config.js.map +1 -1
- package/dist/constants.js +26 -6
- package/dist/constants.js.map +1 -1
- package/dist/hashTree/constants.js +3 -1
- package/dist/hashTree/constants.js.map +1 -1
- package/dist/hashTree/hashTree.js +18 -0
- package/dist/hashTree/hashTree.js.map +1 -1
- package/dist/hashTree/hashTreeParser.js +709 -380
- package/dist/hashTree/hashTreeParser.js.map +1 -1
- package/dist/hashTree/types.js +4 -2
- package/dist/hashTree/types.js.map +1 -1
- package/dist/hashTree/utils.js +10 -0
- package/dist/hashTree/utils.js.map +1 -1
- package/dist/index.js +11 -2
- package/dist/index.js.map +1 -1
- package/dist/interceptors/constant.js +12 -0
- package/dist/interceptors/constant.js.map +1 -0
- package/dist/interceptors/dataChannelAuthToken.js +233 -0
- package/dist/interceptors/dataChannelAuthToken.js.map +1 -0
- package/dist/interceptors/index.js +7 -0
- package/dist/interceptors/index.js.map +1 -1
- package/dist/interpretation/index.js +2 -2
- package/dist/interpretation/index.js.map +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/controlsUtils.js +5 -3
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +125 -68
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/selfUtils.js +1 -0
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/locus-info/types.js.map +1 -1
- package/dist/media/MediaConnectionAwaiter.js +57 -1
- package/dist/media/MediaConnectionAwaiter.js.map +1 -1
- package/dist/media/properties.js +4 -2
- package/dist/media/properties.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +7 -1
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +209 -90
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/request.js +50 -0
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/request.type.js.map +1 -1
- package/dist/meeting/util.js +128 -2
- package/dist/meeting/util.js.map +1 -1
- package/dist/meetings/index.js +78 -36
- package/dist/meetings/index.js.map +1 -1
- package/dist/member/index.js +10 -0
- package/dist/member/index.js.map +1 -1
- package/dist/member/util.js +10 -0
- package/dist/member/util.js.map +1 -1
- package/dist/metrics/constants.js +2 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +1 -1
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js +11 -0
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/reactions/reactions.type.js.map +1 -1
- package/dist/types/aiEnableRequest/index.d.ts +5 -0
- package/dist/types/aiEnableRequest/utils.d.ts +2 -0
- package/dist/types/config.d.ts +3 -0
- package/dist/types/constants.d.ts +21 -1
- package/dist/types/hashTree/constants.d.ts +1 -0
- package/dist/types/hashTree/hashTree.d.ts +7 -0
- package/dist/types/hashTree/hashTreeParser.d.ts +99 -14
- package/dist/types/hashTree/types.d.ts +3 -0
- package/dist/types/hashTree/utils.d.ts +6 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/interceptors/constant.d.ts +5 -0
- package/dist/types/interceptors/dataChannelAuthToken.d.ts +35 -0
- package/dist/types/interceptors/index.d.ts +2 -1
- package/dist/types/locus-info/index.d.ts +9 -2
- package/dist/types/locus-info/types.d.ts +1 -0
- package/dist/types/media/MediaConnectionAwaiter.d.ts +10 -1
- package/dist/types/media/properties.d.ts +2 -1
- package/dist/types/meeting/in-meeting-actions.d.ts +6 -0
- package/dist/types/meeting/index.d.ts +24 -2
- package/dist/types/meeting/request.d.ts +16 -1
- package/dist/types/meeting/request.type.d.ts +5 -0
- package/dist/types/meeting/util.d.ts +31 -0
- package/dist/types/meetings/index.d.ts +4 -2
- package/dist/types/member/index.d.ts +1 -0
- package/dist/types/member/util.d.ts +5 -0
- package/dist/types/metrics/constants.d.ts +1 -0
- package/dist/types/reactions/reactions.type.d.ts +1 -0
- package/dist/webinar/index.js +1 -1
- package/package.json +22 -22
- package/src/aiEnableRequest/README.md +84 -0
- package/src/aiEnableRequest/index.ts +170 -0
- package/src/aiEnableRequest/utils.ts +25 -0
- package/src/annotation/index.ts +7 -4
- package/src/config.ts +3 -0
- package/src/constants.ts +26 -1
- package/src/hashTree/constants.ts +1 -0
- package/src/hashTree/hashTree.ts +17 -0
- package/src/hashTree/hashTreeParser.ts +627 -249
- package/src/hashTree/types.ts +4 -0
- package/src/hashTree/utils.ts +9 -0
- package/src/index.ts +8 -1
- package/src/interceptors/constant.ts +6 -0
- package/src/interceptors/dataChannelAuthToken.ts +142 -0
- package/src/interceptors/index.ts +2 -1
- package/src/interpretation/index.ts +2 -2
- package/src/locus-info/controlsUtils.ts +11 -0
- package/src/locus-info/index.ts +146 -58
- package/src/locus-info/selfUtils.ts +1 -0
- package/src/locus-info/types.ts +1 -0
- package/src/media/MediaConnectionAwaiter.ts +41 -1
- package/src/media/properties.ts +3 -1
- package/src/meeting/in-meeting-actions.ts +12 -0
- package/src/meeting/index.ts +127 -17
- package/src/meeting/request.ts +42 -0
- package/src/meeting/request.type.ts +6 -0
- package/src/meeting/util.ts +156 -1
- package/src/meetings/index.ts +94 -9
- package/src/member/index.ts +10 -0
- package/src/member/util.ts +12 -0
- package/src/metrics/constants.ts +1 -0
- package/src/multistream/mediaRequestManager.ts +1 -1
- package/src/multistream/remoteMediaManager.ts +13 -0
- package/src/reactions/reactions.type.ts +1 -0
- package/test/unit/spec/aiEnableRequest/index.ts +981 -0
- package/test/unit/spec/aiEnableRequest/utils.ts +130 -0
- package/test/unit/spec/hashTree/hashTree.ts +66 -0
- package/test/unit/spec/hashTree/hashTreeParser.ts +1869 -189
- package/test/unit/spec/interceptors/dataChannelAuthToken.ts +141 -0
- package/test/unit/spec/locus-info/controlsUtils.js +29 -0
- package/test/unit/spec/locus-info/index.js +201 -45
- package/test/unit/spec/media/MediaConnectionAwaiter.ts +41 -1
- package/test/unit/spec/media/properties.ts +12 -3
- package/test/unit/spec/meeting/in-meeting-actions.ts +8 -2
- package/test/unit/spec/meeting/index.js +441 -75
- package/test/unit/spec/meeting/request.js +64 -0
- package/test/unit/spec/meeting/utils.js +433 -22
- package/test/unit/spec/meetings/index.js +550 -10
- package/test/unit/spec/member/index.js +28 -4
- package/test/unit/spec/member/util.js +65 -27
- package/test/unit/spec/multistream/remoteMediaManager.ts +30 -0
|
@@ -5,7 +5,7 @@ var _Array$from = require("@babel/runtime-corejs2/core-js/array/from");
|
|
|
5
5
|
var _Symbol = require("@babel/runtime-corejs2/core-js/symbol");
|
|
6
6
|
var _Symbol$iterator = require("@babel/runtime-corejs2/core-js/symbol/iterator");
|
|
7
7
|
var _Array$isArray2 = require("@babel/runtime-corejs2/core-js/array/is-array");
|
|
8
|
-
var _Object$
|
|
8
|
+
var _Object$keys4 = require("@babel/runtime-corejs2/core-js/object/keys");
|
|
9
9
|
var _Object$getOwnPropertySymbols = require("@babel/runtime-corejs2/core-js/object/get-own-property-symbols");
|
|
10
10
|
var _Object$getOwnPropertyDescriptor = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptor");
|
|
11
11
|
var _Object$getOwnPropertyDescriptors = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptors");
|
|
@@ -15,7 +15,7 @@ var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequ
|
|
|
15
15
|
_Object$defineProperty(exports, "__esModule", {
|
|
16
16
|
value: true
|
|
17
17
|
});
|
|
18
|
-
exports.default = exports.LocusInfoUpdateType = void 0;
|
|
18
|
+
exports.default = exports.MeetingEndedError = exports.LocusInfoUpdateType = void 0;
|
|
19
19
|
var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));
|
|
20
20
|
var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
|
|
21
21
|
var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));
|
|
@@ -40,7 +40,7 @@ var _loggerProxy = _interopRequireDefault(require("../common/logs/logger-proxy")
|
|
|
40
40
|
var _constants = require("../constants");
|
|
41
41
|
var _constants2 = require("./constants");
|
|
42
42
|
var _utils = require("./utils");
|
|
43
|
-
function ownKeys(e, r) { var t = _Object$
|
|
43
|
+
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; }
|
|
44
44
|
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; }
|
|
45
45
|
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof _Symbol && r[_Symbol$iterator] || r["@@iterator"]; if (!t) { if (_Array$isArray2(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
46
46
|
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? _Array$from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
@@ -55,7 +55,7 @@ var LocusInfoUpdateType = exports.LocusInfoUpdateType = {
|
|
|
55
55
|
* This error is thrown if we receive information that the meeting has ended while we're processing some hash messages.
|
|
56
56
|
* It's handled internally by HashTreeParser and results in MEETING_ENDED being sent up.
|
|
57
57
|
*/
|
|
58
|
-
var MeetingEndedError = /*#__PURE__*/function (_Error) {
|
|
58
|
+
var MeetingEndedError = exports.MeetingEndedError = /*#__PURE__*/function (_Error) {
|
|
59
59
|
function MeetingEndedError() {
|
|
60
60
|
(0, _classCallCheck2.default)(this, MeetingEndedError);
|
|
61
61
|
return _callSuper(this, MeetingEndedError, arguments);
|
|
@@ -63,6 +63,12 @@ var MeetingEndedError = /*#__PURE__*/function (_Error) {
|
|
|
63
63
|
(0, _inherits2.default)(MeetingEndedError, _Error);
|
|
64
64
|
return (0, _createClass2.default)(MeetingEndedError);
|
|
65
65
|
}(/*#__PURE__*/(0, _wrapNativeSuper2.default)(Error));
|
|
66
|
+
/* Currently Locus always sends Metadata objects only in the "self" dataset.
|
|
67
|
+
* If this ever changes, update all the code that relies on this constant.
|
|
68
|
+
*/
|
|
69
|
+
var MetadataDataSetName = _constants2.DataSetNames.SELF;
|
|
70
|
+
var PossibleSentinelMessageDataSetNames = [_constants2.DataSetNames.MAIN, _constants2.DataSetNames.SELF, _constants2.DataSetNames.UNJOINED];
|
|
71
|
+
|
|
66
72
|
/**
|
|
67
73
|
* Parses hash tree eventing locus data
|
|
68
74
|
*/
|
|
@@ -73,7 +79,13 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
73
79
|
* @param {Object} options.initialLocus The initial locus data containing the hash tree information
|
|
74
80
|
*/
|
|
75
81
|
function HashTreeParser(options) {
|
|
76
|
-
var _locus$
|
|
82
|
+
var _locus$links,
|
|
83
|
+
_locus$links$resource,
|
|
84
|
+
_locus$links$resource2,
|
|
85
|
+
_options$metadata,
|
|
86
|
+
_this = this,
|
|
87
|
+
_options$metadata2,
|
|
88
|
+
_options$metadata2$vi;
|
|
77
89
|
(0, _classCallCheck2.default)(this, HashTreeParser);
|
|
78
90
|
(0, _defineProperty2.default)(this, "dataSets", {});
|
|
79
91
|
(0, _defineProperty2.default)(this, "visibleDataSetsUrl", void 0);
|
|
@@ -82,6 +94,8 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
82
94
|
(0, _defineProperty2.default)(this, "locusInfoUpdateCallback", void 0);
|
|
83
95
|
(0, _defineProperty2.default)(this, "visibleDataSets", void 0);
|
|
84
96
|
(0, _defineProperty2.default)(this, "debugId", void 0);
|
|
97
|
+
(0, _defineProperty2.default)(this, "heartbeatIntervalMs", void 0);
|
|
98
|
+
(0, _defineProperty2.default)(this, "excludedDataSets", void 0);
|
|
85
99
|
var _options$initialLocus = options.initialLocus,
|
|
86
100
|
dataSets = _options$initialLocus.dataSets,
|
|
87
101
|
locus = _options$initialLocus.locus; // extract dataSets from initialLocus
|
|
@@ -89,12 +103,20 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
89
103
|
this.debugId = options.debugId;
|
|
90
104
|
this.webexRequest = options.webexRequest;
|
|
91
105
|
this.locusInfoUpdateCallback = options.locusInfoUpdateCallback;
|
|
92
|
-
this.
|
|
93
|
-
|
|
94
|
-
|
|
106
|
+
this.excludedDataSets = options.excludedDataSets || [];
|
|
107
|
+
this.visibleDataSetsUrl = locus === null || locus === void 0 ? void 0 : (_locus$links = locus.links) === null || _locus$links === void 0 ? void 0 : (_locus$links$resource = _locus$links.resources) === null || _locus$links$resource === void 0 ? void 0 : (_locus$links$resource2 = _locus$links$resource.visibleDataSets) === null || _locus$links$resource2 === void 0 ? void 0 : _locus$links$resource2.url;
|
|
108
|
+
this.visibleDataSets = (0, _lodash.cloneDeep)(((_options$metadata = options.metadata) === null || _options$metadata === void 0 ? void 0 : _options$metadata.visibleDataSets) || []).filter(function (vds) {
|
|
109
|
+
return !_this.isExcludedDataSet(vds.name);
|
|
110
|
+
});
|
|
111
|
+
if (((_options$metadata2 = options.metadata) === null || _options$metadata2 === void 0 ? void 0 : (_options$metadata2$vi = _options$metadata2.visibleDataSets) === null || _options$metadata2$vi === void 0 ? void 0 : _options$metadata2$vi.length) === 0) {
|
|
112
|
+
_loggerProxy.default.logger.warn("HashTreeParser#constructor --> ".concat(this.debugId, " No visibleDataSets found in Metadata"));
|
|
95
113
|
}
|
|
96
114
|
// object mapping dataset names to arrays of leaf data
|
|
97
115
|
var leafData = this.analyzeLocusHtMeta(locus);
|
|
116
|
+
if (options.metadata) {
|
|
117
|
+
// add also the metadata that's outside of locus object itself
|
|
118
|
+
this.analyzeMetadata(leafData, options.metadata);
|
|
119
|
+
}
|
|
98
120
|
_loggerProxy.default.logger.info("HashTreeParser#constructor --> creating HashTreeParser for datasets: ".concat((0, _stringify.default)(dataSets.map(function (ds) {
|
|
99
121
|
return ds.name;
|
|
100
122
|
}))));
|
|
@@ -106,7 +128,7 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
106
128
|
var name = dataSet.name,
|
|
107
129
|
leafCount = dataSet.leafCount;
|
|
108
130
|
this.dataSets[name] = _objectSpread(_objectSpread({}, dataSet), {}, {
|
|
109
|
-
hashTree: this.
|
|
131
|
+
hashTree: this.isVisibleDataSet(name) ? new _hashTree.default(leafData[name] || [], leafCount) : undefined
|
|
110
132
|
});
|
|
111
133
|
}
|
|
112
134
|
} catch (err) {
|
|
@@ -117,30 +139,78 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
117
139
|
}
|
|
118
140
|
|
|
119
141
|
/**
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
* @param {DataSet} dataSet The new data set to be added
|
|
125
|
-
* @returns {Promise}
|
|
142
|
+
* Checks if the given data set name is in the list of visible data sets
|
|
143
|
+
* @param {string} dataSetName data set name to check
|
|
144
|
+
* @returns {Boolean} True if the data set is visible, false otherwise
|
|
126
145
|
*/
|
|
127
146
|
return (0, _createClass2.default)(HashTreeParser, [{
|
|
147
|
+
key: "isVisibleDataSet",
|
|
148
|
+
value: function isVisibleDataSet(dataSetName) {
|
|
149
|
+
return this.visibleDataSets.some(function (vds) {
|
|
150
|
+
return vds.name === dataSetName;
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Checks if the given data set name is in the excluded list
|
|
156
|
+
* @param {string} dataSetName data set name to check
|
|
157
|
+
* @returns {boolean} True if the data set is excluded, false otherwise
|
|
158
|
+
*/
|
|
159
|
+
}, {
|
|
160
|
+
key: "isExcludedDataSet",
|
|
161
|
+
value: function isExcludedDataSet(dataSetName) {
|
|
162
|
+
return this.excludedDataSets.some(function (name) {
|
|
163
|
+
return name === dataSetName;
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Adds a data set to the visible data sets list, unless it is in the excluded list.
|
|
169
|
+
* @param {VisibleDataSetInfo} dataSetInfo data set info to add
|
|
170
|
+
* @returns {boolean} True if the data set was added, false if it was excluded
|
|
171
|
+
*/
|
|
172
|
+
}, {
|
|
173
|
+
key: "addToVisibleDataSetsList",
|
|
174
|
+
value: function addToVisibleDataSetsList(dataSetInfo) {
|
|
175
|
+
if (this.isExcludedDataSet(dataSetInfo.name)) {
|
|
176
|
+
_loggerProxy.default.logger.info("HashTreeParser#addToVisibleDataSetsList --> ".concat(this.debugId, " Data set \"").concat(dataSetInfo.name, "\" is in the excluded list, ignoring"));
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
this.visibleDataSets.push(dataSetInfo);
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Initializes a new visible data set by creating a hash tree for it, adding it to all the internal structures,
|
|
185
|
+
* and sending an initial sync request to Locus with empty leaf data - that will trigger Locus to gives us all the data
|
|
186
|
+
* from that dataset (in the response or via messages).
|
|
187
|
+
*
|
|
188
|
+
* @param {VisibleDataSetInfo} visibleDataSetInfo Information about the new visible data set
|
|
189
|
+
* @param {DataSet} dataSetInfo The new data set to be added
|
|
190
|
+
* @returns {Promise}
|
|
191
|
+
*/
|
|
192
|
+
}, {
|
|
128
193
|
key: "initializeNewVisibleDataSet",
|
|
129
|
-
value: function initializeNewVisibleDataSet(
|
|
130
|
-
if (this.
|
|
131
|
-
_loggerProxy.default.logger.info("HashTreeParser#initializeNewVisibleDataSet --> ".concat(this.debugId, " Data set \"").concat(
|
|
194
|
+
value: function initializeNewVisibleDataSet(visibleDataSetInfo, dataSetInfo) {
|
|
195
|
+
if (this.isVisibleDataSet(dataSetInfo.name)) {
|
|
196
|
+
_loggerProxy.default.logger.info("HashTreeParser#initializeNewVisibleDataSet --> ".concat(this.debugId, " Data set \"").concat(dataSetInfo.name, "\" already exists, skipping init"));
|
|
197
|
+
return _promise.default.resolve({
|
|
198
|
+
updateType: LocusInfoUpdateType.OBJECTS_UPDATED,
|
|
199
|
+
updatedObjects: []
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
_loggerProxy.default.logger.info("HashTreeParser#initializeNewVisibleDataSet --> ".concat(this.debugId, " Adding visible data set \"").concat(dataSetInfo.name, "\""));
|
|
203
|
+
if (!this.addToVisibleDataSetsList(visibleDataSetInfo)) {
|
|
132
204
|
return _promise.default.resolve({
|
|
133
205
|
updateType: LocusInfoUpdateType.OBJECTS_UPDATED,
|
|
134
206
|
updatedObjects: []
|
|
135
207
|
});
|
|
136
208
|
}
|
|
137
|
-
|
|
138
|
-
this.
|
|
139
|
-
var hashTree = new _hashTree.default([], dataSet.leafCount);
|
|
140
|
-
this.dataSets[dataSet.name] = _objectSpread(_objectSpread({}, dataSet), {}, {
|
|
209
|
+
var hashTree = new _hashTree.default([], dataSetInfo.leafCount);
|
|
210
|
+
this.dataSets[dataSetInfo.name] = _objectSpread(_objectSpread({}, dataSetInfo), {}, {
|
|
141
211
|
hashTree: hashTree
|
|
142
212
|
});
|
|
143
|
-
return this.sendInitializationSyncRequestToLocus(
|
|
213
|
+
return this.sendInitializationSyncRequestToLocus(dataSetInfo.name, 'new visible data set');
|
|
144
214
|
}
|
|
145
215
|
|
|
146
216
|
/**
|
|
@@ -153,7 +223,7 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
153
223
|
}, {
|
|
154
224
|
key: "sendInitializationSyncRequestToLocus",
|
|
155
225
|
value: function sendInitializationSyncRequestToLocus(datasetName, debugText) {
|
|
156
|
-
var
|
|
226
|
+
var _this2 = this;
|
|
157
227
|
var dataset = this.dataSets[datasetName];
|
|
158
228
|
if (!dataset) {
|
|
159
229
|
_loggerProxy.default.logger.warn("HashTreeParser#sendInitializationSyncRequestToLocus --> ".concat(this.debugId, " No data set found for ").concat(datasetName, ", cannot send the request for leaf data"));
|
|
@@ -163,7 +233,10 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
163
233
|
_loggerProxy.default.logger.info("HashTreeParser#sendInitializationSyncRequestToLocus --> ".concat(this.debugId, " Sending initial sync request to Locus for data set \"").concat(datasetName, "\" with empty leaf data"));
|
|
164
234
|
return this.sendSyncRequestToLocus(this.dataSets[datasetName], emptyLeavesData).then(function (syncResponse) {
|
|
165
235
|
if (syncResponse) {
|
|
166
|
-
return
|
|
236
|
+
return {
|
|
237
|
+
updateType: LocusInfoUpdateType.OBJECTS_UPDATED,
|
|
238
|
+
updatedObjects: _this2.parseMessage(syncResponse, "via empty leaves /sync API call for ".concat(debugText))
|
|
239
|
+
};
|
|
167
240
|
}
|
|
168
241
|
return {
|
|
169
242
|
updateType: LocusInfoUpdateType.OBJECTS_UPDATED,
|
|
@@ -173,19 +246,26 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
173
246
|
}
|
|
174
247
|
|
|
175
248
|
/**
|
|
176
|
-
* Queries Locus for information about all
|
|
249
|
+
* Queries Locus for all up-to-date information about all visible data sets
|
|
177
250
|
*
|
|
178
|
-
* @param {string} url - url from which we can get info about all data sets
|
|
179
251
|
* @returns {Promise}
|
|
180
252
|
*/
|
|
181
253
|
}, {
|
|
182
|
-
key: "
|
|
183
|
-
value: function
|
|
254
|
+
key: "getAllVisibleDataSetsFromLocus",
|
|
255
|
+
value: function getAllVisibleDataSetsFromLocus() {
|
|
256
|
+
var _this3 = this;
|
|
257
|
+
if (!this.visibleDataSetsUrl) {
|
|
258
|
+
_loggerProxy.default.logger.warn("HashTreeParser#getAllVisibleDataSetsFromLocus --> ".concat(this.debugId, " No visibleDataSetsUrl, cannot get data sets information"));
|
|
259
|
+
return _promise.default.resolve([]);
|
|
260
|
+
}
|
|
184
261
|
return this.webexRequest({
|
|
185
262
|
method: _constants.HTTP_VERBS.GET,
|
|
186
|
-
uri:
|
|
263
|
+
uri: this.visibleDataSetsUrl
|
|
187
264
|
}).then(function (response) {
|
|
188
265
|
return response.body.dataSets;
|
|
266
|
+
}).catch(function (error) {
|
|
267
|
+
_this3.checkForSentinelHttpResponse(error);
|
|
268
|
+
throw error;
|
|
189
269
|
});
|
|
190
270
|
}
|
|
191
271
|
|
|
@@ -199,17 +279,18 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
199
279
|
key: "initializeFromMessage",
|
|
200
280
|
value: (function () {
|
|
201
281
|
var _initializeFromMessage = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee(message) {
|
|
202
|
-
var
|
|
282
|
+
var visibleDataSets;
|
|
203
283
|
return _regenerator.default.wrap(function (_context) {
|
|
204
284
|
while (1) switch (_context.prev = _context.next) {
|
|
205
285
|
case 0:
|
|
206
|
-
|
|
286
|
+
this.visibleDataSetsUrl = message.visibleDataSetsUrl;
|
|
287
|
+
_loggerProxy.default.logger.info("HashTreeParser#initializeFromMessage --> ".concat(this.debugId, " visibleDataSetsUrl=").concat(this.visibleDataSetsUrl));
|
|
207
288
|
_context.next = 1;
|
|
208
|
-
return this.
|
|
289
|
+
return this.getAllVisibleDataSetsFromLocus();
|
|
209
290
|
case 1:
|
|
210
|
-
|
|
291
|
+
visibleDataSets = _context.sent;
|
|
211
292
|
_context.next = 2;
|
|
212
|
-
return this.initializeDataSets(
|
|
293
|
+
return this.initializeDataSets(visibleDataSets, 'initialization from message');
|
|
213
294
|
case 2:
|
|
214
295
|
case "end":
|
|
215
296
|
return _context.stop();
|
|
@@ -235,25 +316,26 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
235
316
|
key: "initializeFromGetLociResponse",
|
|
236
317
|
value: (function () {
|
|
237
318
|
var _initializeFromGetLociResponse = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee2(locus) {
|
|
238
|
-
var _locus$
|
|
239
|
-
var
|
|
319
|
+
var _locus$links2, _locus$links2$resourc, _locus$links2$resourc2;
|
|
320
|
+
var visibleDataSets;
|
|
240
321
|
return _regenerator.default.wrap(function (_context2) {
|
|
241
322
|
while (1) switch (_context2.prev = _context2.next) {
|
|
242
323
|
case 0:
|
|
243
|
-
if (locus !== null && locus !== void 0 && (_locus$
|
|
324
|
+
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) {
|
|
244
325
|
_context2.next = 1;
|
|
245
326
|
break;
|
|
246
327
|
}
|
|
247
328
|
_loggerProxy.default.logger.warn("HashTreeParser#initializeFromGetLociResponse --> ".concat(this.debugId, " missing visibleDataSets url in GET Loci response, cannot initialize hash trees"));
|
|
248
329
|
return _context2.abrupt("return");
|
|
249
330
|
case 1:
|
|
250
|
-
|
|
331
|
+
this.visibleDataSetsUrl = locus.links.resources.visibleDataSets.url;
|
|
332
|
+
_loggerProxy.default.logger.info("HashTreeParser#initializeFromGetLociResponse --> ".concat(this.debugId, " visibleDataSets url: ").concat(this.visibleDataSetsUrl));
|
|
251
333
|
_context2.next = 2;
|
|
252
|
-
return this.
|
|
334
|
+
return this.getAllVisibleDataSetsFromLocus();
|
|
253
335
|
case 2:
|
|
254
|
-
|
|
336
|
+
visibleDataSets = _context2.sent;
|
|
255
337
|
_context2.next = 3;
|
|
256
|
-
return this.initializeDataSets(
|
|
338
|
+
return this.initializeDataSets(visibleDataSets, 'initialization from GET /loci response');
|
|
257
339
|
case 3:
|
|
258
340
|
case "end":
|
|
259
341
|
return _context2.stop();
|
|
@@ -268,7 +350,7 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
268
350
|
/**
|
|
269
351
|
* Initializes data sets by doing an initialization sync on each visible data set that doesn't have a hash tree yet.
|
|
270
352
|
*
|
|
271
|
-
* @param {DataSet[]}
|
|
353
|
+
* @param {DataSet[]} visibleDataSets Array of visible DataSet objects to initialize
|
|
272
354
|
* @param {string} debugText Text to include in logs for debugging purposes
|
|
273
355
|
* @returns {Promise}
|
|
274
356
|
*/
|
|
@@ -276,13 +358,13 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
276
358
|
}, {
|
|
277
359
|
key: "initializeDataSets",
|
|
278
360
|
value: (function () {
|
|
279
|
-
var _initializeDataSets = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee3(
|
|
280
|
-
var updatedObjects, _iterator2, _step2, dataSet, name, leafCount, _data, _t;
|
|
361
|
+
var _initializeDataSets = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee3(visibleDataSets, debugText) {
|
|
362
|
+
var updatedObjects, _iterator2, _step2, dataSet, name, leafCount, url, _data, _t;
|
|
281
363
|
return _regenerator.default.wrap(function (_context3) {
|
|
282
364
|
while (1) switch (_context3.prev = _context3.next) {
|
|
283
365
|
case 0:
|
|
284
366
|
updatedObjects = [];
|
|
285
|
-
_iterator2 = _createForOfIteratorHelper(
|
|
367
|
+
_iterator2 = _createForOfIteratorHelper(visibleDataSets);
|
|
286
368
|
_context3.prev = 1;
|
|
287
369
|
_iterator2.s();
|
|
288
370
|
case 2:
|
|
@@ -291,14 +373,27 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
291
373
|
break;
|
|
292
374
|
}
|
|
293
375
|
dataSet = _step2.value;
|
|
294
|
-
name = dataSet.name, leafCount = dataSet.leafCount;
|
|
376
|
+
name = dataSet.name, leafCount = dataSet.leafCount, url = dataSet.url;
|
|
295
377
|
if (!this.dataSets[name]) {
|
|
296
378
|
_loggerProxy.default.logger.info("HashTreeParser#initializeDataSets --> ".concat(this.debugId, " initializing dataset \"").concat(name, "\" (").concat(debugText, ")"));
|
|
297
379
|
this.dataSets[name] = _objectSpread({}, dataSet);
|
|
298
380
|
} else {
|
|
299
381
|
_loggerProxy.default.logger.info("HashTreeParser#initializeDataSets --> ".concat(this.debugId, " dataset \"").concat(name, "\" already exists (").concat(debugText, ")"));
|
|
300
382
|
}
|
|
301
|
-
if (
|
|
383
|
+
if (this.isVisibleDataSet(name)) {
|
|
384
|
+
_context3.next = 3;
|
|
385
|
+
break;
|
|
386
|
+
}
|
|
387
|
+
if (this.addToVisibleDataSetsList({
|
|
388
|
+
name: name,
|
|
389
|
+
url: url
|
|
390
|
+
})) {
|
|
391
|
+
_context3.next = 3;
|
|
392
|
+
break;
|
|
393
|
+
}
|
|
394
|
+
return _context3.abrupt("continue", 5);
|
|
395
|
+
case 3:
|
|
396
|
+
if (this.dataSets[name].hashTree) {
|
|
302
397
|
_context3.next = 5;
|
|
303
398
|
break;
|
|
304
399
|
}
|
|
@@ -306,19 +401,10 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
306
401
|
this.dataSets[name].hashTree = new _hashTree.default([], leafCount);
|
|
307
402
|
|
|
308
403
|
// eslint-disable-next-line no-await-in-loop
|
|
309
|
-
_context3.next =
|
|
404
|
+
_context3.next = 4;
|
|
310
405
|
return this.sendInitializationSyncRequestToLocus(name, debugText);
|
|
311
|
-
case 3:
|
|
312
|
-
_data = _context3.sent;
|
|
313
|
-
if (!(_data.updateType === LocusInfoUpdateType.MEETING_ENDED)) {
|
|
314
|
-
_context3.next = 4;
|
|
315
|
-
break;
|
|
316
|
-
}
|
|
317
|
-
_loggerProxy.default.logger.warn("HashTreeParser#initializeDataSets --> ".concat(this.debugId, " meeting ended while initializing new visible data set \"").concat(name, "\""));
|
|
318
|
-
|
|
319
|
-
// throw an error, it will be caught higher up and the meeting will be destroyed
|
|
320
|
-
throw new MeetingEndedError();
|
|
321
406
|
case 4:
|
|
407
|
+
_data = _context3.sent;
|
|
322
408
|
if (_data.updateType === LocusInfoUpdateType.OBJECTS_UPDATED) {
|
|
323
409
|
updatedObjects.push.apply(updatedObjects, (0, _toConsumableArray2.default)(_data.updatedObjects || []));
|
|
324
410
|
}
|
|
@@ -434,6 +520,38 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
434
520
|
return leafInfo;
|
|
435
521
|
}
|
|
436
522
|
|
|
523
|
+
/**
|
|
524
|
+
* Analyzes the Metadata object that is sent outside of Locus object, and appends its data to passed in leafInfo
|
|
525
|
+
* structure.
|
|
526
|
+
*
|
|
527
|
+
* @param {Record<string, LeafInfo[]>} leafInfo the structure to which the Metadata info will be appended
|
|
528
|
+
* @param {Metadata} metadata Metadata object
|
|
529
|
+
* @returns {void}
|
|
530
|
+
*/
|
|
531
|
+
}, {
|
|
532
|
+
key: "analyzeMetadata",
|
|
533
|
+
value: function analyzeMetadata(leafInfo, metadata) {
|
|
534
|
+
var _htMeta$dataSetNames;
|
|
535
|
+
var htMeta = metadata.htMeta;
|
|
536
|
+
if ((htMeta === null || htMeta === void 0 ? void 0 : (_htMeta$dataSetNames = htMeta.dataSetNames) === null || _htMeta$dataSetNames === void 0 ? void 0 : _htMeta$dataSetNames.length) === 1 && htMeta.dataSetNames[0].toLowerCase() === MetadataDataSetName) {
|
|
537
|
+
var _metadata$htMeta$elem = metadata.htMeta.elementId,
|
|
538
|
+
type = _metadata$htMeta$elem.type,
|
|
539
|
+
id = _metadata$htMeta$elem.id,
|
|
540
|
+
version = _metadata$htMeta$elem.version;
|
|
541
|
+
var dataSetName = htMeta.dataSetNames[0];
|
|
542
|
+
if (!leafInfo[dataSetName]) {
|
|
543
|
+
leafInfo[dataSetName] = [];
|
|
544
|
+
}
|
|
545
|
+
leafInfo[dataSetName].push({
|
|
546
|
+
type: type,
|
|
547
|
+
id: id,
|
|
548
|
+
version: version
|
|
549
|
+
});
|
|
550
|
+
} else {
|
|
551
|
+
throw new Error("".concat(this.debugId, " Metadata htMeta has unexpected dataSetNames: ").concat(htMeta && htMeta.dataSetNames.join(',')));
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
|
|
437
555
|
/**
|
|
438
556
|
* Checks if the provided hash tree message indicates the end of the meeting and that there won't be any more updates.
|
|
439
557
|
*
|
|
@@ -443,14 +561,14 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
443
561
|
}, {
|
|
444
562
|
key: "isEndMessage",
|
|
445
563
|
value: function isEndMessage(message) {
|
|
446
|
-
var
|
|
447
|
-
|
|
564
|
+
var _this4 = this;
|
|
565
|
+
return message.dataSets.some(function (dataSet) {
|
|
566
|
+
if (dataSet.leafCount === 1 && dataSet.root === _constants2.EMPTY_HASH && (!_this4.dataSets[dataSet.name] || _this4.dataSets[dataSet.name].version < dataSet.version) && PossibleSentinelMessageDataSetNames.includes(dataSet.name.toLowerCase())) {
|
|
567
|
+
// this is a special way for Locus to indicate that this meeting has ended
|
|
568
|
+
return true;
|
|
569
|
+
}
|
|
570
|
+
return false;
|
|
448
571
|
});
|
|
449
|
-
if (mainDataSet && mainDataSet.leafCount === 1 && mainDataSet.root === _constants2.EMPTY_HASH && this.dataSets[_constants2.DataSetNames.MAIN].version < mainDataSet.version) {
|
|
450
|
-
// this is a special way for Locus to indicate that this meeting has ended
|
|
451
|
-
return true;
|
|
452
|
-
}
|
|
453
|
-
return false;
|
|
454
572
|
}
|
|
455
573
|
|
|
456
574
|
/**
|
|
@@ -462,7 +580,7 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
462
580
|
}, {
|
|
463
581
|
key: "handleRootHashHeartBeatMessage",
|
|
464
582
|
value: function handleRootHashHeartBeatMessage(message) {
|
|
465
|
-
var
|
|
583
|
+
var _this5 = this;
|
|
466
584
|
var dataSets = message.dataSets;
|
|
467
585
|
_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) {
|
|
468
586
|
var name = _ref2.name,
|
|
@@ -477,11 +595,78 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
477
595
|
};
|
|
478
596
|
}))));
|
|
479
597
|
dataSets.forEach(function (dataSet) {
|
|
480
|
-
|
|
481
|
-
|
|
598
|
+
_this5.updateDataSetInfo(dataSet);
|
|
599
|
+
_this5.runSyncAlgorithm(dataSet);
|
|
482
600
|
});
|
|
483
601
|
}
|
|
484
602
|
|
|
603
|
+
/**
|
|
604
|
+
* Asynchronously initializes new visible data sets
|
|
605
|
+
*
|
|
606
|
+
* @param {VisibleDataSetInfo[]} dataSetsRequiringInitialization list of datasets to initialize
|
|
607
|
+
* @returns {void}
|
|
608
|
+
*/
|
|
609
|
+
}, {
|
|
610
|
+
key: "queueInitForNewVisibleDataSets",
|
|
611
|
+
value: function queueInitForNewVisibleDataSets(dataSetsRequiringInitialization) {
|
|
612
|
+
var _this6 = this;
|
|
613
|
+
queueMicrotask(function () {
|
|
614
|
+
_this6.initializeNewVisibleDataSets(dataSetsRequiringInitialization).catch(function (error) {
|
|
615
|
+
if (error instanceof MeetingEndedError) {
|
|
616
|
+
_this6.callLocusInfoUpdateCallback({
|
|
617
|
+
updateType: LocusInfoUpdateType.MEETING_ENDED
|
|
618
|
+
});
|
|
619
|
+
} else {
|
|
620
|
+
_loggerProxy.default.logger.warn("HashTreeParser#queueInitForNewVisibleDataSets --> ".concat(_this6.debugId, " error while initializing new visible datasets: ").concat(dataSetsRequiringInitialization.map(function (ds) {
|
|
621
|
+
return ds.name;
|
|
622
|
+
}).join(', '), ": "), error);
|
|
623
|
+
}
|
|
624
|
+
});
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
/**
|
|
629
|
+
* Handles updates to Metadata object that we receive from Locus via other means than messages. Right now
|
|
630
|
+
* that means only in the API response alongside locus object.
|
|
631
|
+
*
|
|
632
|
+
* @param {Metadata} metadata received in Locus update other than a message (for example in an API response)
|
|
633
|
+
* @param {HashTreeObject[]} updatedObjects a list of updated hash tree objects to which any updates resulting from new Metadata will be added
|
|
634
|
+
* @returns {void}
|
|
635
|
+
*/
|
|
636
|
+
}, {
|
|
637
|
+
key: "handleMetadataUpdate",
|
|
638
|
+
value: function handleMetadataUpdate(metadata, updatedObjects) {
|
|
639
|
+
var _this$dataSets$Metada;
|
|
640
|
+
var dataSetsRequiringInitialization = [];
|
|
641
|
+
|
|
642
|
+
// current assumption based on Locus docs is that Metadata object lives always in "self" data set
|
|
643
|
+
var hashTree = (_this$dataSets$Metada = this.dataSets[MetadataDataSetName]) === null || _this$dataSets$Metada === void 0 ? void 0 : _this$dataSets$Metada.hashTree;
|
|
644
|
+
if (!hashTree) {
|
|
645
|
+
_loggerProxy.default.logger.warn("HashTreeParser#handleLocusUpdate --> ".concat(this.debugId, " received Metadata object but no hash tree for \"").concat(MetadataDataSetName, "\" data set exists"));
|
|
646
|
+
} else {
|
|
647
|
+
var metadataUpdated = hashTree.putItem(metadata.htMeta.elementId);
|
|
648
|
+
if (metadataUpdated) {
|
|
649
|
+
// metadata in Locus API response is in a slightly different format than the objects in messages, so need to adapt it
|
|
650
|
+
var metadataObject = {
|
|
651
|
+
htMeta: metadata.htMeta,
|
|
652
|
+
data: metadata
|
|
653
|
+
};
|
|
654
|
+
updatedObjects.push(metadataObject);
|
|
655
|
+
var _this$checkForVisible = this.checkForVisibleDataSetChanges([metadataObject]),
|
|
656
|
+
changeDetected = _this$checkForVisible.changeDetected,
|
|
657
|
+
removedDataSets = _this$checkForVisible.removedDataSets,
|
|
658
|
+
addedDataSets = _this$checkForVisible.addedDataSets;
|
|
659
|
+
if (changeDetected) {
|
|
660
|
+
dataSetsRequiringInitialization = this.processVisibleDataSetChanges(removedDataSets, addedDataSets, updatedObjects);
|
|
661
|
+
}
|
|
662
|
+
if (dataSetsRequiringInitialization.length > 0) {
|
|
663
|
+
// there are some data sets that we need to initialize asynchronously
|
|
664
|
+
this.queueInitForNewVisibleDataSets(dataSetsRequiringInitialization);
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
|
|
485
670
|
/**
|
|
486
671
|
* This method should be called when we receive a partial locus DTO that contains dataSets and htMeta information
|
|
487
672
|
* It updates the hash trees with the new leaf data based on the received Locus
|
|
@@ -492,23 +677,25 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
492
677
|
}, {
|
|
493
678
|
key: "handleLocusUpdate",
|
|
494
679
|
value: function handleLocusUpdate(update) {
|
|
495
|
-
var
|
|
680
|
+
var _this7 = this;
|
|
496
681
|
var dataSets = update.dataSets,
|
|
497
|
-
locus = update.locus
|
|
682
|
+
locus = update.locus,
|
|
683
|
+
metadata = update.metadata;
|
|
498
684
|
if (!dataSets) {
|
|
499
|
-
_loggerProxy.default.logger.
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
685
|
+
_loggerProxy.default.logger.info("HashTreeParser#handleLocusUpdate --> ".concat(this.debugId, " received hash tree update without dataSets"));
|
|
686
|
+
} else {
|
|
687
|
+
var _iterator5 = _createForOfIteratorHelper(dataSets),
|
|
688
|
+
_step5;
|
|
689
|
+
try {
|
|
690
|
+
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
|
691
|
+
var dataSet = _step5.value;
|
|
692
|
+
this.updateDataSetInfo(dataSet);
|
|
693
|
+
}
|
|
694
|
+
} catch (err) {
|
|
695
|
+
_iterator5.e(err);
|
|
696
|
+
} finally {
|
|
697
|
+
_iterator5.f();
|
|
507
698
|
}
|
|
508
|
-
} catch (err) {
|
|
509
|
-
_iterator5.e(err);
|
|
510
|
-
} finally {
|
|
511
|
-
_iterator5.f();
|
|
512
699
|
}
|
|
513
700
|
var updatedObjects = [];
|
|
514
701
|
|
|
@@ -517,11 +704,16 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
517
704
|
copyData: true
|
|
518
705
|
});
|
|
519
706
|
|
|
707
|
+
// if we got metadata, process it (currently that means only potential visible data set list changes)
|
|
708
|
+
if (metadata) {
|
|
709
|
+
this.handleMetadataUpdate(metadata, updatedObjects);
|
|
710
|
+
}
|
|
711
|
+
|
|
520
712
|
// then process the data in hash trees, if it is a new version, then add it to updatedObjects
|
|
521
713
|
(0, _keys.default)(leafInfo).forEach(function (dataSetName) {
|
|
522
|
-
if (
|
|
523
|
-
if (
|
|
524
|
-
var appliedChangesList =
|
|
714
|
+
if (_this7.dataSets[dataSetName]) {
|
|
715
|
+
if (_this7.dataSets[dataSetName].hashTree) {
|
|
716
|
+
var appliedChangesList = _this7.dataSets[dataSetName].hashTree.putItems(leafInfo[dataSetName].map(function (leaf) {
|
|
525
717
|
return {
|
|
526
718
|
id: leaf.id,
|
|
527
719
|
type: leaf.type,
|
|
@@ -548,10 +740,10 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
548
740
|
});
|
|
549
741
|
} else {
|
|
550
742
|
// no hash tree means that the data set is not visible
|
|
551
|
-
_loggerProxy.default.logger.warn("HashTreeParser#handleLocusUpdate --> ".concat(
|
|
743
|
+
_loggerProxy.default.logger.warn("HashTreeParser#handleLocusUpdate --> ".concat(_this7.debugId, " received leaf data for data set \"").concat(dataSetName, "\" that has no hash tree created, ignoring"));
|
|
552
744
|
}
|
|
553
745
|
} else {
|
|
554
|
-
_loggerProxy.default.logger.warn("HashTreeParser#handleLocusUpdate --> ".concat(
|
|
746
|
+
_loggerProxy.default.logger.warn("HashTreeParser#handleLocusUpdate --> ".concat(_this7.debugId, " received leaf data for unknown data set \"").concat(dataSetName, "\", ignoring"));
|
|
555
747
|
}
|
|
556
748
|
});
|
|
557
749
|
if (updatedObjects.length === 0) {
|
|
@@ -562,9 +754,6 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
562
754
|
updatedObjects: updatedObjects
|
|
563
755
|
});
|
|
564
756
|
}
|
|
565
|
-
|
|
566
|
-
// todo: once Locus design on how visible data sets will be communicated in subsequent API responses is confirmed,
|
|
567
|
-
// we'll need to check here if visible data sets have changed and update this.visibleDataSets, remove/create hash trees etc
|
|
568
757
|
}
|
|
569
758
|
|
|
570
759
|
/**
|
|
@@ -578,7 +767,7 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
578
767
|
value: function updateDataSetInfo(receivedDataSet) {
|
|
579
768
|
if (!this.dataSets[receivedDataSet.name]) {
|
|
580
769
|
this.dataSets[receivedDataSet.name] = _objectSpread({}, receivedDataSet);
|
|
581
|
-
_loggerProxy.default.logger.info("HashTreeParser#
|
|
770
|
+
_loggerProxy.default.logger.info("HashTreeParser#updateDataSetInfo --> ".concat(this.debugId, " created entry for \"").concat(receivedDataSet.name, "\" dataset: version=").concat(receivedDataSet.version, ", root=").concat(receivedDataSet.root));
|
|
582
771
|
return;
|
|
583
772
|
}
|
|
584
773
|
// update our version of the dataSet
|
|
@@ -590,7 +779,7 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
590
779
|
maxMs: receivedDataSet.backoff.maxMs,
|
|
591
780
|
exponent: receivedDataSet.backoff.exponent
|
|
592
781
|
};
|
|
593
|
-
_loggerProxy.default.logger.info("HashTreeParser#
|
|
782
|
+
_loggerProxy.default.logger.info("HashTreeParser#updateDataSetInfo --> ".concat(this.debugId, " updated \"").concat(receivedDataSet.name, "\" dataset to version=").concat(receivedDataSet.version, ", root=").concat(receivedDataSet.root));
|
|
594
783
|
}
|
|
595
784
|
}
|
|
596
785
|
|
|
@@ -602,24 +791,33 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
602
791
|
}, {
|
|
603
792
|
key: "checkForVisibleDataSetChanges",
|
|
604
793
|
value: function checkForVisibleDataSetChanges(updatedObjects) {
|
|
605
|
-
var
|
|
794
|
+
var _this8 = this;
|
|
606
795
|
var removedDataSets = [];
|
|
607
796
|
var addedDataSets = [];
|
|
608
797
|
|
|
609
|
-
// visibleDataSets can only be changed by
|
|
798
|
+
// visibleDataSets can only be changed by Metadata object updates
|
|
610
799
|
updatedObjects.forEach(function (object) {
|
|
611
800
|
var _object$data;
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
removedDataSets = _this4.visibleDataSets.filter(function (ds) {
|
|
616
|
-
return !newVisibleDataSets.includes(ds);
|
|
801
|
+
if ((0, _utils.isMetadata)(object) && (_object$data = object.data) !== null && _object$data !== void 0 && _object$data.visibleDataSets) {
|
|
802
|
+
var newVisibleDataSets = object.data.visibleDataSets.filter(function (vds) {
|
|
803
|
+
return !_this8.isExcludedDataSet(vds.name);
|
|
617
804
|
});
|
|
618
|
-
|
|
619
|
-
return !
|
|
805
|
+
removedDataSets = _this8.visibleDataSets.filter(function (ds) {
|
|
806
|
+
return !newVisibleDataSets.some(function (nvs) {
|
|
807
|
+
return nvs.name === ds.name;
|
|
808
|
+
});
|
|
809
|
+
});
|
|
810
|
+
addedDataSets = newVisibleDataSets.filter(function (nvs) {
|
|
811
|
+
return _this8.visibleDataSets.every(function (ds) {
|
|
812
|
+
return ds.name !== nvs.name;
|
|
813
|
+
});
|
|
620
814
|
});
|
|
621
815
|
if (removedDataSets.length > 0 || addedDataSets.length > 0) {
|
|
622
|
-
_loggerProxy.default.logger.info("HashTreeParser#checkForVisibleDataSetChanges --> ".concat(
|
|
816
|
+
_loggerProxy.default.logger.info("HashTreeParser#checkForVisibleDataSetChanges --> ".concat(_this8.debugId, " visible data sets change: removed: ").concat(removedDataSets.map(function (ds) {
|
|
817
|
+
return ds.name;
|
|
818
|
+
}).join(', '), ", added: ").concat(addedDataSets.map(function (ds) {
|
|
819
|
+
return ds.name;
|
|
820
|
+
}).join(', ')));
|
|
623
821
|
}
|
|
624
822
|
}
|
|
625
823
|
});
|
|
@@ -641,11 +839,15 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
641
839
|
value: function deleteHashTree(dataSetName) {
|
|
642
840
|
this.dataSets[dataSetName].hashTree = undefined;
|
|
643
841
|
|
|
644
|
-
// we also need to stop the
|
|
842
|
+
// we also need to stop the timers as there is no hash tree anymore to sync
|
|
645
843
|
if (this.dataSets[dataSetName].timer) {
|
|
646
844
|
clearTimeout(this.dataSets[dataSetName].timer);
|
|
647
845
|
this.dataSets[dataSetName].timer = undefined;
|
|
648
846
|
}
|
|
847
|
+
if (this.dataSets[dataSetName].heartbeatWatchdogTimer) {
|
|
848
|
+
clearTimeout(this.dataSets[dataSetName].heartbeatWatchdogTimer);
|
|
849
|
+
this.dataSets[dataSetName].heartbeatWatchdogTimer = undefined;
|
|
850
|
+
}
|
|
649
851
|
}
|
|
650
852
|
|
|
651
853
|
/**
|
|
@@ -657,38 +859,40 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
657
859
|
* visible data sets and they require async initialization, the names of these data sets
|
|
658
860
|
* are returned in an array.
|
|
659
861
|
*
|
|
660
|
-
* @param {
|
|
661
|
-
* @param {
|
|
862
|
+
* @param {VisibleDataSetInfo[]} removedDataSets - The list of removed data sets.
|
|
863
|
+
* @param {VisibleDataSetInfo[]} addedDataSets - The list of added data sets.
|
|
662
864
|
* @param {HashTreeObject[]} updatedObjects - The list of updated hash tree objects to which changes will be added.
|
|
663
|
-
* @returns {
|
|
865
|
+
* @returns {VisibleDataSetInfo[]} list of data sets that couldn't be initialized synchronously
|
|
664
866
|
*/
|
|
665
867
|
}, {
|
|
666
868
|
key: "processVisibleDataSetChanges",
|
|
667
869
|
value: function processVisibleDataSetChanges(removedDataSets, addedDataSets, updatedObjects) {
|
|
668
|
-
var
|
|
870
|
+
var _this9 = this;
|
|
669
871
|
var dataSetsRequiringInitialization = [];
|
|
670
872
|
|
|
671
873
|
// if a visible data set was removed, we need to tell our client that all objects from it are removed
|
|
672
874
|
var removedObjects = [];
|
|
673
875
|
removedDataSets.forEach(function (ds) {
|
|
674
|
-
var
|
|
675
|
-
if ((
|
|
676
|
-
for (var i = 0; i <
|
|
677
|
-
removedObjects.push.apply(removedObjects, (0, _toConsumableArray2.default)(
|
|
876
|
+
var _this9$dataSets$ds$na;
|
|
877
|
+
if ((_this9$dataSets$ds$na = _this9.dataSets[ds.name]) !== null && _this9$dataSets$ds$na !== void 0 && _this9$dataSets$ds$na.hashTree) {
|
|
878
|
+
for (var i = 0; i < _this9.dataSets[ds.name].hashTree.numLeaves; i += 1) {
|
|
879
|
+
removedObjects.push.apply(removedObjects, (0, _toConsumableArray2.default)(_this9.dataSets[ds.name].hashTree.getLeafData(i).map(function (elementId) {
|
|
678
880
|
return {
|
|
679
881
|
htMeta: {
|
|
680
882
|
elementId: elementId,
|
|
681
|
-
dataSetNames: [ds]
|
|
883
|
+
dataSetNames: [ds.name]
|
|
682
884
|
},
|
|
683
885
|
data: null
|
|
684
886
|
};
|
|
685
887
|
})));
|
|
686
888
|
}
|
|
687
|
-
|
|
889
|
+
_this9.deleteHashTree(ds.name);
|
|
688
890
|
}
|
|
689
891
|
});
|
|
690
892
|
this.visibleDataSets = this.visibleDataSets.filter(function (vds) {
|
|
691
|
-
return !removedDataSets.
|
|
893
|
+
return !removedDataSets.some(function (rds) {
|
|
894
|
+
return rds.name === vds.name;
|
|
895
|
+
});
|
|
692
896
|
});
|
|
693
897
|
updatedObjects.push.apply(updatedObjects, removedObjects);
|
|
694
898
|
|
|
@@ -698,22 +902,25 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
698
902
|
try {
|
|
699
903
|
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
|
|
700
904
|
var ds = _step6.value;
|
|
701
|
-
var dataSetInfo = this.dataSets[ds];
|
|
905
|
+
var dataSetInfo = this.dataSets[ds.name];
|
|
702
906
|
if (dataSetInfo) {
|
|
703
|
-
if (this.
|
|
704
|
-
_loggerProxy.default.logger.info("HashTreeParser#processVisibleDataSetChanges --> ".concat(this.debugId, " Data set \"").concat(ds, "\" is already visible, skipping"));
|
|
907
|
+
if (this.isVisibleDataSet(dataSetInfo.name)) {
|
|
908
|
+
_loggerProxy.default.logger.info("HashTreeParser#processVisibleDataSetChanges --> ".concat(this.debugId, " Data set \"").concat(ds.name, "\" is already visible, skipping"));
|
|
705
909
|
|
|
706
910
|
// eslint-disable-next-line no-continue
|
|
707
911
|
continue;
|
|
708
912
|
}
|
|
709
|
-
_loggerProxy.default.logger.info("HashTreeParser#processVisibleDataSetChanges --> ".concat(this.debugId, " Adding visible data set \"").concat(ds, "\""));
|
|
710
|
-
this.
|
|
913
|
+
_loggerProxy.default.logger.info("HashTreeParser#processVisibleDataSetChanges --> ".concat(this.debugId, " Adding visible data set \"").concat(ds.name, "\""));
|
|
914
|
+
if (!this.addToVisibleDataSetsList(ds)) {
|
|
915
|
+
// eslint-disable-next-line no-continue
|
|
916
|
+
continue;
|
|
917
|
+
}
|
|
711
918
|
var hashTree = new _hashTree.default([], dataSetInfo.leafCount);
|
|
712
919
|
this.dataSets[dataSetInfo.name] = _objectSpread(_objectSpread({}, dataSetInfo), {}, {
|
|
713
920
|
hashTree: hashTree
|
|
714
921
|
});
|
|
715
922
|
} else {
|
|
716
|
-
_loggerProxy.default.logger.info("HashTreeParser#processVisibleDataSetChanges --> ".concat(this.debugId, " visible data set \"").concat(ds, "\" added but no info about it in our dataSets structures"));
|
|
923
|
+
_loggerProxy.default.logger.info("HashTreeParser#processVisibleDataSetChanges --> ".concat(this.debugId, " visible data set \"").concat(ds.name, "\" added but no info about it in our dataSets structures"));
|
|
717
924
|
// todo: add a metric here
|
|
718
925
|
dataSetsRequiringInitialization.push(ds);
|
|
719
926
|
}
|
|
@@ -730,21 +937,20 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
730
937
|
* Adds entries to the passed in updateObjects array
|
|
731
938
|
* for the changes that result from adding and removing visible data sets.
|
|
732
939
|
*
|
|
733
|
-
* @param {
|
|
734
|
-
* @param {string[]} addedDataSets - The list of added data sets.
|
|
940
|
+
* @param {VisibleDataSetInfo[]} addedDataSets - The list of added data sets.
|
|
735
941
|
* @returns {Promise<void>}
|
|
736
942
|
*/
|
|
737
943
|
}, {
|
|
738
944
|
key: "initializeNewVisibleDataSets",
|
|
739
945
|
value: (function () {
|
|
740
|
-
var _initializeNewVisibleDataSets = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee4(
|
|
741
|
-
var
|
|
946
|
+
var _initializeNewVisibleDataSets = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee4(addedDataSets) {
|
|
947
|
+
var _this0 = this;
|
|
742
948
|
var allDataSets, _iterator7, _step7, _loop, _t2;
|
|
743
949
|
return _regenerator.default.wrap(function (_context5) {
|
|
744
950
|
while (1) switch (_context5.prev = _context5.next) {
|
|
745
951
|
case 0:
|
|
746
952
|
_context5.next = 1;
|
|
747
|
-
return this.
|
|
953
|
+
return this.getAllVisibleDataSetsFromLocus();
|
|
748
954
|
case 1:
|
|
749
955
|
allDataSets = _context5.sent;
|
|
750
956
|
_iterator7 = _createForOfIteratorHelper(addedDataSets);
|
|
@@ -756,22 +962,22 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
756
962
|
case 0:
|
|
757
963
|
ds = _step7.value;
|
|
758
964
|
dataSetInfo = allDataSets.find(function (d) {
|
|
759
|
-
return d.name === ds;
|
|
965
|
+
return d.name === ds.name;
|
|
760
966
|
});
|
|
761
|
-
_loggerProxy.default.logger.info("HashTreeParser#initializeNewVisibleDataSets --> ".concat(
|
|
967
|
+
_loggerProxy.default.logger.info("HashTreeParser#initializeNewVisibleDataSets --> ".concat(_this0.debugId, " initializing data set \"").concat(ds.name, "\""));
|
|
762
968
|
if (dataSetInfo) {
|
|
763
969
|
_context4.next = 1;
|
|
764
970
|
break;
|
|
765
971
|
}
|
|
766
|
-
_loggerProxy.default.logger.warn("HashTreeParser#handleHashTreeMessage --> ".concat(
|
|
972
|
+
_loggerProxy.default.logger.warn("HashTreeParser#handleHashTreeMessage --> ".concat(_this0.debugId, " missing info about data set \"").concat(ds.name, "\" in Locus response from visibleDataSetsUrl"));
|
|
767
973
|
_context4.next = 3;
|
|
768
974
|
break;
|
|
769
975
|
case 1:
|
|
770
976
|
_context4.next = 2;
|
|
771
|
-
return
|
|
977
|
+
return _this0.initializeNewVisibleDataSet(ds, dataSetInfo);
|
|
772
978
|
case 2:
|
|
773
979
|
updates = _context4.sent;
|
|
774
|
-
|
|
980
|
+
_this0.callLocusInfoUpdateCallback(updates);
|
|
775
981
|
case 3:
|
|
776
982
|
case "end":
|
|
777
983
|
return _context4.stop();
|
|
@@ -805,7 +1011,7 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
805
1011
|
}
|
|
806
1012
|
}, _callee4, this, [[2, 6, 7, 8]]);
|
|
807
1013
|
}));
|
|
808
|
-
function initializeNewVisibleDataSets(_x5
|
|
1014
|
+
function initializeNewVisibleDataSets(_x5) {
|
|
809
1015
|
return _initializeNewVisibleDataSets.apply(this, arguments);
|
|
810
1016
|
}
|
|
811
1017
|
return initializeNewVisibleDataSets;
|
|
@@ -815,156 +1021,116 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
815
1021
|
*
|
|
816
1022
|
* @param {HashTreeMessage} message - The hash tree message containing data sets and objects to be processed
|
|
817
1023
|
* @param {string} [debugText] - Optional debug text to include in logs
|
|
818
|
-
* @returns {
|
|
1024
|
+
* @returns {HashTreeObject[]} list of hash tree objects that were updated as a result of processing the message
|
|
819
1025
|
*/
|
|
820
1026
|
)
|
|
821
1027
|
}, {
|
|
822
1028
|
key: "parseMessage",
|
|
823
|
-
value:
|
|
824
|
-
var
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
_loggerProxy.default.logger.warn("HashTreeParser#parseMessage --> ".concat(this.debugId, " got empty locusStateElements!!!"));
|
|
835
|
-
// todo: send a metric
|
|
836
|
-
}
|
|
1029
|
+
value: function parseMessage(message, debugText) {
|
|
1030
|
+
var _message$locusStateEl,
|
|
1031
|
+
_this1 = this,
|
|
1032
|
+
_message$locusStateEl2;
|
|
1033
|
+
var dataSets = message.dataSets,
|
|
1034
|
+
visibleDataSetsUrl = message.visibleDataSetsUrl;
|
|
1035
|
+
_loggerProxy.default.logger.info("HashTreeParser#parseMessage --> ".concat(this.debugId, " received message ").concat(debugText || '', ":"), message);
|
|
1036
|
+
if (((_message$locusStateEl = message.locusStateElements) === null || _message$locusStateEl === void 0 ? void 0 : _message$locusStateEl.length) === 0) {
|
|
1037
|
+
_loggerProxy.default.logger.warn("HashTreeParser#parseMessage --> ".concat(this.debugId, " got empty locusStateElements!!!"));
|
|
1038
|
+
// todo: send a metric
|
|
1039
|
+
}
|
|
837
1040
|
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
_context6.next = 1;
|
|
845
|
-
break;
|
|
846
|
-
}
|
|
847
|
-
_loggerProxy.default.logger.info("HashTreeParser#parseMessage --> ".concat(this.debugId, " received END message"));
|
|
848
|
-
this.stopAllTimers();
|
|
849
|
-
return _context6.abrupt("return", {
|
|
850
|
-
updateType: LocusInfoUpdateType.MEETING_ENDED
|
|
851
|
-
});
|
|
852
|
-
case 1:
|
|
853
|
-
isRosterDropped = false;
|
|
854
|
-
updatedObjects = []; // when we detect new visible datasets, it may be that the metadata about them is not
|
|
855
|
-
// available in the message, they will require separate async initialization
|
|
856
|
-
dataSetsRequiringInitialization = []; // first find out if there are any visible data set changes - they're signalled in SELF object updates
|
|
857
|
-
selfUpdates = (message.locusStateElements || []).filter(function (object) {
|
|
858
|
-
return (
|
|
859
|
-
// todo: SPARK-744859 once Locus supports it, we will filter for "Metadata" type here instead of "self"
|
|
860
|
-
(0, _utils.isSelf)(object)
|
|
861
|
-
);
|
|
862
|
-
});
|
|
863
|
-
if (selfUpdates.length > 0) {
|
|
864
|
-
updatedSelfObjects = [];
|
|
865
|
-
selfUpdates.forEach(function (object) {
|
|
866
|
-
// todo: once Locus supports it, we will use the "view" field here instead of dataSetNames
|
|
867
|
-
var _iterator8 = _createForOfIteratorHelper(object.htMeta.dataSetNames),
|
|
868
|
-
_step8;
|
|
869
|
-
try {
|
|
870
|
-
for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
|
|
871
|
-
var _this7$dataSets$dataS;
|
|
872
|
-
var dataSetName = _step8.value;
|
|
873
|
-
var hashTree = (_this7$dataSets$dataS = _this7.dataSets[dataSetName]) === null || _this7$dataSets$dataS === void 0 ? void 0 : _this7$dataSets$dataS.hashTree;
|
|
874
|
-
if (hashTree && object.data) {
|
|
875
|
-
if (hashTree.putItem(object.htMeta.elementId)) {
|
|
876
|
-
updatedSelfObjects.push(object);
|
|
877
|
-
}
|
|
878
|
-
}
|
|
879
|
-
}
|
|
880
|
-
} catch (err) {
|
|
881
|
-
_iterator8.e(err);
|
|
882
|
-
} finally {
|
|
883
|
-
_iterator8.f();
|
|
884
|
-
}
|
|
885
|
-
});
|
|
886
|
-
updatedObjects.push.apply(updatedObjects, updatedSelfObjects);
|
|
887
|
-
_this$checkForVisible = this.checkForVisibleDataSetChanges(updatedSelfObjects), changeDetected = _this$checkForVisible.changeDetected, removedDataSets = _this$checkForVisible.removedDataSets, addedDataSets = _this$checkForVisible.addedDataSets;
|
|
888
|
-
if (changeDetected) {
|
|
889
|
-
dataSetsRequiringInitialization = this.processVisibleDataSetChanges(removedDataSets, addedDataSets, updatedObjects);
|
|
890
|
-
}
|
|
891
|
-
}
|
|
1041
|
+
// first, update our metadata about the datasets with info from the message
|
|
1042
|
+
this.visibleDataSetsUrl = visibleDataSetsUrl;
|
|
1043
|
+
dataSets.forEach(function (dataSet) {
|
|
1044
|
+
return _this1.updateDataSetInfo(dataSet);
|
|
1045
|
+
});
|
|
1046
|
+
var updatedObjects = [];
|
|
892
1047
|
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
object = _ref6[1];
|
|
916
|
-
if (changeApplied) {
|
|
917
|
-
if ((0, _utils.isSelf)(object) && !object.data) {
|
|
918
|
-
isRosterDropped = true;
|
|
919
|
-
}
|
|
920
|
-
// add to updatedObjects so that our locus DTO will get updated with the new object
|
|
921
|
-
updatedObjects.push(object);
|
|
922
|
-
}
|
|
923
|
-
});
|
|
924
|
-
} else {
|
|
925
|
-
_loggerProxy.default.logger.info("Locus-info:index#parseMessage --> ".concat(_this7.debugId, " unexpected (not visible) dataSet ").concat(dataSet.name, " received in hash tree message"));
|
|
926
|
-
}
|
|
927
|
-
}
|
|
928
|
-
if (!isRosterDropped) {
|
|
929
|
-
_this7.runSyncAlgorithm(dataSet);
|
|
1048
|
+
// when we detect new visible datasets, it may be that the metadata about them is not
|
|
1049
|
+
// available in the message, they will require separate async initialization
|
|
1050
|
+
var dataSetsRequiringInitialization = [];
|
|
1051
|
+
|
|
1052
|
+
// first find out if there are any visible data set changes - they're signalled in Metadata object updates
|
|
1053
|
+
var metadataUpdates = (message.locusStateElements || []).filter(function (object) {
|
|
1054
|
+
return (0, _utils.isMetadata)(object);
|
|
1055
|
+
});
|
|
1056
|
+
if (metadataUpdates.length > 0) {
|
|
1057
|
+
var updatedMetadataObjects = [];
|
|
1058
|
+
metadataUpdates.forEach(function (object) {
|
|
1059
|
+
// todo: once Locus supports it, we will use the "view" field here instead of dataSetNames
|
|
1060
|
+
var _iterator8 = _createForOfIteratorHelper(object.htMeta.dataSetNames),
|
|
1061
|
+
_step8;
|
|
1062
|
+
try {
|
|
1063
|
+
for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
|
|
1064
|
+
var _this1$dataSets$dataS;
|
|
1065
|
+
var dataSetName = _step8.value;
|
|
1066
|
+
var hashTree = (_this1$dataSets$dataS = _this1.dataSets[dataSetName]) === null || _this1$dataSets$dataS === void 0 ? void 0 : _this1$dataSets$dataS.hashTree;
|
|
1067
|
+
if (hashTree && object.data) {
|
|
1068
|
+
if (hashTree.putItem(object.htMeta.elementId)) {
|
|
1069
|
+
updatedMetadataObjects.push(object);
|
|
930
1070
|
}
|
|
931
|
-
});
|
|
932
|
-
if (!isRosterDropped) {
|
|
933
|
-
_context6.next = 2;
|
|
934
|
-
break;
|
|
935
1071
|
}
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
1072
|
+
}
|
|
1073
|
+
} catch (err) {
|
|
1074
|
+
_iterator8.e(err);
|
|
1075
|
+
} finally {
|
|
1076
|
+
_iterator8.f();
|
|
1077
|
+
}
|
|
1078
|
+
});
|
|
1079
|
+
updatedObjects.push.apply(updatedObjects, updatedMetadataObjects);
|
|
1080
|
+
var _this$checkForVisible2 = this.checkForVisibleDataSetChanges(updatedMetadataObjects),
|
|
1081
|
+
changeDetected = _this$checkForVisible2.changeDetected,
|
|
1082
|
+
removedDataSets = _this$checkForVisible2.removedDataSets,
|
|
1083
|
+
addedDataSets = _this$checkForVisible2.addedDataSets;
|
|
1084
|
+
if (changeDetected) {
|
|
1085
|
+
dataSetsRequiringInitialization = this.processVisibleDataSetChanges(removedDataSets, addedDataSets, updatedObjects);
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
if (((_message$locusStateEl2 = message.locusStateElements) === null || _message$locusStateEl2 === void 0 ? void 0 : _message$locusStateEl2.length) > 0) {
|
|
1089
|
+
// by this point we now have this.dataSets setup for data sets from this message
|
|
1090
|
+
// and hash trees created for the new visible data sets,
|
|
1091
|
+
// so we can now process all the updates from the message
|
|
1092
|
+
dataSets.forEach(function (dataSet) {
|
|
1093
|
+
if (_this1.dataSets[dataSet.name]) {
|
|
1094
|
+
var hashTree = _this1.dataSets[dataSet.name].hashTree;
|
|
1095
|
+
if (hashTree) {
|
|
1096
|
+
var locusStateElementsForThisSet = message.locusStateElements.filter(function (object) {
|
|
1097
|
+
return object.htMeta.dataSetNames.includes(dataSet.name);
|
|
942
1098
|
});
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
1099
|
+
var appliedChangesList = hashTree.updateItems(locusStateElementsForThisSet.map(function (object) {
|
|
1100
|
+
return object.data ? {
|
|
1101
|
+
operation: 'update',
|
|
1102
|
+
item: object.htMeta.elementId
|
|
1103
|
+
} : {
|
|
1104
|
+
operation: 'remove',
|
|
1105
|
+
item: object.htMeta.elementId
|
|
1106
|
+
};
|
|
1107
|
+
}));
|
|
1108
|
+
(0, _lodash.zip)(appliedChangesList, locusStateElementsForThisSet).forEach(function (_ref5) {
|
|
1109
|
+
var _ref6 = (0, _slicedToArray2.default)(_ref5, 2),
|
|
1110
|
+
changeApplied = _ref6[0],
|
|
1111
|
+
object = _ref6[1];
|
|
1112
|
+
if (changeApplied) {
|
|
1113
|
+
// add to updatedObjects so that our locus DTO will get updated with the new object
|
|
1114
|
+
updatedObjects.push(object);
|
|
1115
|
+
}
|
|
956
1116
|
});
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
1117
|
+
} else {
|
|
1118
|
+
_loggerProxy.default.logger.info("Locus-info:index#parseMessage --> ".concat(_this1.debugId, " unexpected (not visible) dataSet ").concat(dataSet.name, " received in hash tree message"));
|
|
1119
|
+
}
|
|
960
1120
|
}
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
function parseMessage(_x7, _x8) {
|
|
964
|
-
return _parseMessage.apply(this, arguments);
|
|
1121
|
+
_this1.runSyncAlgorithm(dataSet);
|
|
1122
|
+
});
|
|
965
1123
|
}
|
|
966
|
-
|
|
967
|
-
|
|
1124
|
+
if (dataSetsRequiringInitialization.length > 0) {
|
|
1125
|
+
// there are some data sets that we need to initialize asynchronously
|
|
1126
|
+
this.queueInitForNewVisibleDataSets(dataSetsRequiringInitialization);
|
|
1127
|
+
}
|
|
1128
|
+
if (updatedObjects.length === 0) {
|
|
1129
|
+
_loggerProxy.default.logger.info("HashTreeParser#parseMessage --> ".concat(this.debugId, " No objects updated as a result of received message"));
|
|
1130
|
+
}
|
|
1131
|
+
return updatedObjects;
|
|
1132
|
+
}
|
|
1133
|
+
|
|
968
1134
|
/**
|
|
969
1135
|
* Handles incoming hash tree messages, updates the hash trees and calls locusInfoUpdateCallback
|
|
970
1136
|
*
|
|
@@ -972,52 +1138,83 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
972
1138
|
* @param {string} [debugText] - Optional debug text to include in logs
|
|
973
1139
|
* @returns {void}
|
|
974
1140
|
*/
|
|
975
|
-
)
|
|
976
1141
|
}, {
|
|
977
1142
|
key: "handleMessage",
|
|
978
|
-
value:
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
return _regenerator.default.wrap(function (_context7) {
|
|
982
|
-
while (1) switch (_context7.prev = _context7.next) {
|
|
983
|
-
case 0:
|
|
984
|
-
if (!(message.locusStateElements === undefined)) {
|
|
985
|
-
_context7.next = 1;
|
|
986
|
-
break;
|
|
987
|
-
}
|
|
988
|
-
this.handleRootHashHeartBeatMessage(message);
|
|
989
|
-
_context7.next = 3;
|
|
990
|
-
break;
|
|
991
|
-
case 1:
|
|
992
|
-
_context7.next = 2;
|
|
993
|
-
return this.parseMessage(message, debugText);
|
|
994
|
-
case 2:
|
|
995
|
-
updates = _context7.sent;
|
|
996
|
-
this.callLocusInfoUpdateCallback(updates);
|
|
997
|
-
case 3:
|
|
998
|
-
case "end":
|
|
999
|
-
return _context7.stop();
|
|
1000
|
-
}
|
|
1001
|
-
}, _callee6, this);
|
|
1002
|
-
}));
|
|
1003
|
-
function handleMessage(_x9, _x0) {
|
|
1004
|
-
return _handleMessage.apply(this, arguments);
|
|
1143
|
+
value: function handleMessage(message, debugText) {
|
|
1144
|
+
if (message.heartbeatIntervalMs) {
|
|
1145
|
+
this.heartbeatIntervalMs = message.heartbeatIntervalMs;
|
|
1005
1146
|
}
|
|
1006
|
-
|
|
1007
|
-
|
|
1147
|
+
if (this.isEndMessage(message)) {
|
|
1148
|
+
_loggerProxy.default.logger.info("HashTreeParser#parseMessage --> ".concat(this.debugId, " received sentinel END MEETING message"));
|
|
1149
|
+
this.stopAllTimers();
|
|
1150
|
+
this.callLocusInfoUpdateCallback({
|
|
1151
|
+
updateType: LocusInfoUpdateType.MEETING_ENDED
|
|
1152
|
+
});
|
|
1153
|
+
} else if (message.locusStateElements === undefined) {
|
|
1154
|
+
this.handleRootHashHeartBeatMessage(message);
|
|
1155
|
+
this.resetHeartbeatWatchdogs(message.dataSets);
|
|
1156
|
+
} else {
|
|
1157
|
+
var updatedObjects = this.parseMessage(message, debugText);
|
|
1158
|
+
this.resetHeartbeatWatchdogs(message.dataSets);
|
|
1159
|
+
this.callLocusInfoUpdateCallback({
|
|
1160
|
+
updateType: LocusInfoUpdateType.OBJECTS_UPDATED,
|
|
1161
|
+
updatedObjects: updatedObjects
|
|
1162
|
+
});
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1008
1166
|
/**
|
|
1009
1167
|
* Calls the updateInfo callback if there are any updates to report
|
|
1010
1168
|
*
|
|
1011
1169
|
* @param {Object} updates parsed from a Locus message
|
|
1012
1170
|
* @returns {void}
|
|
1013
1171
|
*/
|
|
1014
|
-
)
|
|
1015
1172
|
}, {
|
|
1016
1173
|
key: "callLocusInfoUpdateCallback",
|
|
1017
1174
|
value: function callLocusInfoUpdateCallback(updates) {
|
|
1175
|
+
var _this10 = this;
|
|
1018
1176
|
var updateType = updates.updateType,
|
|
1019
1177
|
updatedObjects = updates.updatedObjects;
|
|
1020
|
-
if (updateType
|
|
1178
|
+
if (updateType === LocusInfoUpdateType.OBJECTS_UPDATED && (updatedObjects === null || updatedObjects === void 0 ? void 0 : updatedObjects.length) > 0) {
|
|
1179
|
+
// Filter out updates for objects that already have a higher version in their datasets,
|
|
1180
|
+
// or removals for objects that still exist in any of their datasets
|
|
1181
|
+
var filteredUpdates = updatedObjects.filter(function (object) {
|
|
1182
|
+
var elementId = object.htMeta.elementId;
|
|
1183
|
+
var type = elementId.type,
|
|
1184
|
+
id = elementId.id,
|
|
1185
|
+
version = elementId.version;
|
|
1186
|
+
|
|
1187
|
+
// Check all datasets
|
|
1188
|
+
for (var _i2 = 0, _Object$keys3 = (0, _keys.default)(_this10.dataSets); _i2 < _Object$keys3.length; _i2++) {
|
|
1189
|
+
var dataSetName = _Object$keys3[_i2];
|
|
1190
|
+
var dataSet = _this10.dataSets[dataSetName];
|
|
1191
|
+
|
|
1192
|
+
// only visible datasets have hash trees set
|
|
1193
|
+
if (dataSet !== null && dataSet !== void 0 && dataSet.hashTree) {
|
|
1194
|
+
var existingVersion = dataSet.hashTree.getItemVersion(id, type);
|
|
1195
|
+
if (existingVersion !== undefined) {
|
|
1196
|
+
if (object.data) {
|
|
1197
|
+
// For updates: filter out if any dataset has a higher version
|
|
1198
|
+
if (existingVersion > version) {
|
|
1199
|
+
_loggerProxy.default.logger.info("HashTreeParser#callLocusInfoUpdateCallback --> ".concat(_this10.debugId, " Filtering out update for ").concat(type, ":").concat(id, " v").concat(version, " because dataset \"").concat(dataSetName, "\" has v").concat(existingVersion));
|
|
1200
|
+
return false;
|
|
1201
|
+
}
|
|
1202
|
+
} else if (existingVersion >= version) {
|
|
1203
|
+
// For removals: filter out if the object still exists in any dataset
|
|
1204
|
+
_loggerProxy.default.logger.info("HashTreeParser#callLocusInfoUpdateCallback --> ".concat(_this10.debugId, " Filtering out removal for ").concat(type, ":").concat(id, " v").concat(version, " because dataset \"").concat(dataSetName, "\" still has v").concat(existingVersion));
|
|
1205
|
+
return false;
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
return true;
|
|
1211
|
+
});
|
|
1212
|
+
if (filteredUpdates.length > 0) {
|
|
1213
|
+
this.locusInfoUpdateCallback(updateType, {
|
|
1214
|
+
updatedObjects: filteredUpdates
|
|
1215
|
+
});
|
|
1216
|
+
}
|
|
1217
|
+
} else if (updateType !== LocusInfoUpdateType.OBJECTS_UPDATED) {
|
|
1021
1218
|
this.locusInfoUpdateCallback(updateType, {
|
|
1022
1219
|
updatedObjects: updatedObjects
|
|
1023
1220
|
});
|
|
@@ -1039,16 +1236,117 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1039
1236
|
return Math.round(Math.pow(randomValue, exponent) * maxMs);
|
|
1040
1237
|
}
|
|
1041
1238
|
|
|
1239
|
+
/**
|
|
1240
|
+
* Performs a sync for the given data set.
|
|
1241
|
+
*
|
|
1242
|
+
* @param {InternalDataSet} dataSet - The data set to sync
|
|
1243
|
+
* @param {string} rootHash - Our current root hash for this data set
|
|
1244
|
+
* @param {string} reason - The reason for the sync (used for logging)
|
|
1245
|
+
* @returns {Promise<void>}
|
|
1246
|
+
*/
|
|
1247
|
+
}, {
|
|
1248
|
+
key: "performSync",
|
|
1249
|
+
value: (function () {
|
|
1250
|
+
var _performSync = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee5(dataSet, rootHash, reason) {
|
|
1251
|
+
var mismatchedLeavesData, receivedHashes, _yield$this$getHashes, hashes, latestDataSetInfo, mismatchedLeaveIndexes, syncResponse, _t3, _t4;
|
|
1252
|
+
return _regenerator.default.wrap(function (_context6) {
|
|
1253
|
+
while (1) switch (_context6.prev = _context6.next) {
|
|
1254
|
+
case 0:
|
|
1255
|
+
if (dataSet.hashTree) {
|
|
1256
|
+
_context6.next = 1;
|
|
1257
|
+
break;
|
|
1258
|
+
}
|
|
1259
|
+
return _context6.abrupt("return");
|
|
1260
|
+
case 1:
|
|
1261
|
+
_context6.prev = 1;
|
|
1262
|
+
_loggerProxy.default.logger.info("HashTreeParser#performSync --> ".concat(this.debugId, " ").concat(reason, ", syncing data set \"").concat(dataSet.name, "\""));
|
|
1263
|
+
mismatchedLeavesData = {};
|
|
1264
|
+
if (!(dataSet.leafCount !== 1)) {
|
|
1265
|
+
_context6.next = 7;
|
|
1266
|
+
break;
|
|
1267
|
+
}
|
|
1268
|
+
_context6.prev = 2;
|
|
1269
|
+
_context6.next = 3;
|
|
1270
|
+
return this.getHashesFromLocus(dataSet.name, rootHash);
|
|
1271
|
+
case 3:
|
|
1272
|
+
_yield$this$getHashes = _context6.sent;
|
|
1273
|
+
hashes = _yield$this$getHashes.hashes;
|
|
1274
|
+
latestDataSetInfo = _yield$this$getHashes.dataSet;
|
|
1275
|
+
receivedHashes = hashes;
|
|
1276
|
+
dataSet.hashTree.resize(latestDataSetInfo.leafCount);
|
|
1277
|
+
_context6.next = 6;
|
|
1278
|
+
break;
|
|
1279
|
+
case 4:
|
|
1280
|
+
_context6.prev = 4;
|
|
1281
|
+
_t3 = _context6["catch"](2);
|
|
1282
|
+
if (!(_t3.statusCode === 409)) {
|
|
1283
|
+
_context6.next = 5;
|
|
1284
|
+
break;
|
|
1285
|
+
}
|
|
1286
|
+
// this is a leaf count mismatch, we should do nothing, just wait for another heartbeat message from Locus
|
|
1287
|
+
_loggerProxy.default.logger.info("HashTreeParser#getHashesFromLocus --> ".concat(this.debugId, " Got 409 when fetching hashes for data set \"").concat(dataSet.name, "\": ").concat(_t3.message));
|
|
1288
|
+
return _context6.abrupt("return");
|
|
1289
|
+
case 5:
|
|
1290
|
+
throw _t3;
|
|
1291
|
+
case 6:
|
|
1292
|
+
// identify mismatched leaves
|
|
1293
|
+
mismatchedLeaveIndexes = dataSet.hashTree.diffHashes(receivedHashes);
|
|
1294
|
+
mismatchedLeaveIndexes.forEach(function (index) {
|
|
1295
|
+
mismatchedLeavesData[index] = dataSet.hashTree.getLeafData(index);
|
|
1296
|
+
});
|
|
1297
|
+
_context6.next = 8;
|
|
1298
|
+
break;
|
|
1299
|
+
case 7:
|
|
1300
|
+
mismatchedLeavesData[0] = dataSet.hashTree.getLeafData(0);
|
|
1301
|
+
case 8:
|
|
1302
|
+
if (!((0, _keys.default)(mismatchedLeavesData).length > 0)) {
|
|
1303
|
+
_context6.next = 10;
|
|
1304
|
+
break;
|
|
1305
|
+
}
|
|
1306
|
+
_context6.next = 9;
|
|
1307
|
+
return this.sendSyncRequestToLocus(dataSet, mismatchedLeavesData);
|
|
1308
|
+
case 9:
|
|
1309
|
+
syncResponse = _context6.sent;
|
|
1310
|
+
// sync API may return nothing (in that case data will arrive via messages)
|
|
1311
|
+
// or it may return a response in the same format as messages
|
|
1312
|
+
if (syncResponse) {
|
|
1313
|
+
this.handleMessage(syncResponse, 'via sync API');
|
|
1314
|
+
}
|
|
1315
|
+
case 10:
|
|
1316
|
+
_context6.next = 12;
|
|
1317
|
+
break;
|
|
1318
|
+
case 11:
|
|
1319
|
+
_context6.prev = 11;
|
|
1320
|
+
_t4 = _context6["catch"](1);
|
|
1321
|
+
if (_t4 instanceof MeetingEndedError) {
|
|
1322
|
+
this.callLocusInfoUpdateCallback({
|
|
1323
|
+
updateType: LocusInfoUpdateType.MEETING_ENDED
|
|
1324
|
+
});
|
|
1325
|
+
} else {
|
|
1326
|
+
_loggerProxy.default.logger.warn("HashTreeParser#performSync --> ".concat(this.debugId, " error during sync for data set \"").concat(dataSet.name, "\":"), _t4);
|
|
1327
|
+
}
|
|
1328
|
+
case 12:
|
|
1329
|
+
case "end":
|
|
1330
|
+
return _context6.stop();
|
|
1331
|
+
}
|
|
1332
|
+
}, _callee5, this, [[1, 11], [2, 4]]);
|
|
1333
|
+
}));
|
|
1334
|
+
function performSync(_x6, _x7, _x8) {
|
|
1335
|
+
return _performSync.apply(this, arguments);
|
|
1336
|
+
}
|
|
1337
|
+
return performSync;
|
|
1338
|
+
}()
|
|
1042
1339
|
/**
|
|
1043
1340
|
* Runs the sync algorithm for the given data set.
|
|
1044
1341
|
*
|
|
1045
1342
|
* @param {DataSet} receivedDataSet - The data set to run the sync algorithm for.
|
|
1046
1343
|
* @returns {void}
|
|
1047
1344
|
*/
|
|
1345
|
+
)
|
|
1048
1346
|
}, {
|
|
1049
1347
|
key: "runSyncAlgorithm",
|
|
1050
1348
|
value: function runSyncAlgorithm(receivedDataSet) {
|
|
1051
|
-
var
|
|
1349
|
+
var _this11 = this;
|
|
1052
1350
|
var dataSet = this.dataSets[receivedDataSet.name];
|
|
1053
1351
|
if (!dataSet) {
|
|
1054
1352
|
_loggerProxy.default.logger.warn("HashTreeParser#runSyncAlgorithm --> ".concat(this.debugId, " No data set found for ").concat(receivedDataSet.name, ", skipping sync algorithm"));
|
|
@@ -1069,93 +1367,99 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1069
1367
|
clearTimeout(dataSet.timer);
|
|
1070
1368
|
}
|
|
1071
1369
|
_loggerProxy.default.logger.info("HashTreeParser#runSyncAlgorithm --> ".concat(this.debugId, " setting \"").concat(dataSet.name, "\" sync timer for ").concat(delay));
|
|
1072
|
-
dataSet.timer = setTimeout(/*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function
|
|
1073
|
-
var rootHash
|
|
1074
|
-
return _regenerator.default.wrap(function (
|
|
1075
|
-
while (1) switch (
|
|
1370
|
+
dataSet.timer = setTimeout(/*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee6() {
|
|
1371
|
+
var rootHash;
|
|
1372
|
+
return _regenerator.default.wrap(function (_context7) {
|
|
1373
|
+
while (1) switch (_context7.prev = _context7.next) {
|
|
1076
1374
|
case 0:
|
|
1077
1375
|
dataSet.timer = undefined;
|
|
1078
1376
|
if (dataSet.hashTree) {
|
|
1079
|
-
|
|
1377
|
+
_context7.next = 1;
|
|
1080
1378
|
break;
|
|
1081
1379
|
}
|
|
1082
|
-
_loggerProxy.default.logger.warn("HashTreeParser#runSyncAlgorithm --> ".concat(
|
|
1083
|
-
return
|
|
1380
|
+
_loggerProxy.default.logger.warn("HashTreeParser#runSyncAlgorithm --> ".concat(_this11.debugId, " Data set \"").concat(dataSet.name, "\" no longer has a hash tree, cannot run sync algorithm"));
|
|
1381
|
+
return _context7.abrupt("return");
|
|
1084
1382
|
case 1:
|
|
1085
1383
|
rootHash = dataSet.hashTree.getRootHash();
|
|
1086
1384
|
if (!(dataSet.root !== rootHash)) {
|
|
1087
|
-
|
|
1088
|
-
break;
|
|
1089
|
-
}
|
|
1090
|
-
_loggerProxy.default.logger.info("HashTreeParser#runSyncAlgorithm --> ".concat(_this8.debugId, " Root hash mismatch: received=").concat(dataSet.root, ", ours=").concat(rootHash, ", syncing data set \"").concat(dataSet.name, "\""));
|
|
1091
|
-
mismatchedLeavesData = {};
|
|
1092
|
-
if (!(dataSet.leafCount !== 1)) {
|
|
1093
|
-
_context8.next = 7;
|
|
1385
|
+
_context7.next = 3;
|
|
1094
1386
|
break;
|
|
1095
1387
|
}
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
_yield$_this8$getHash = _context8.sent;
|
|
1101
|
-
hashes = _yield$_this8$getHash.hashes;
|
|
1102
|
-
latestDataSetInfo = _yield$_this8$getHash.dataSet;
|
|
1103
|
-
receivedHashes = hashes;
|
|
1104
|
-
dataSet.hashTree.resize(latestDataSetInfo.leafCount);
|
|
1105
|
-
_context8.next = 6;
|
|
1388
|
+
_context7.next = 2;
|
|
1389
|
+
return _this11.performSync(dataSet, rootHash, "Root hash mismatch: received=".concat(dataSet.root, ", ours=").concat(rootHash));
|
|
1390
|
+
case 2:
|
|
1391
|
+
_context7.next = 4;
|
|
1106
1392
|
break;
|
|
1393
|
+
case 3:
|
|
1394
|
+
_loggerProxy.default.logger.info("HashTreeParser#runSyncAlgorithm --> ".concat(_this11.debugId, " \"").concat(dataSet.name, "\" root hash matching: ").concat(rootHash, ", version=").concat(dataSet.version));
|
|
1107
1395
|
case 4:
|
|
1108
|
-
_context8.prev = 4;
|
|
1109
|
-
_t3 = _context8["catch"](2);
|
|
1110
|
-
if (!(_t3.statusCode === 409)) {
|
|
1111
|
-
_context8.next = 5;
|
|
1112
|
-
break;
|
|
1113
|
-
}
|
|
1114
|
-
// this is a leaf count mismatch, we should do nothing, just wait for another heartbeat message from Locus
|
|
1115
|
-
_loggerProxy.default.logger.info("HashTreeParser#getHashesFromLocus --> ".concat(_this8.debugId, " Got 409 when fetching hashes for data set \"").concat(dataSet.name, "\": ").concat(_t3.message));
|
|
1116
|
-
return _context8.abrupt("return");
|
|
1117
|
-
case 5:
|
|
1118
|
-
throw _t3;
|
|
1119
|
-
case 6:
|
|
1120
|
-
// identify mismatched leaves
|
|
1121
|
-
mismatchedLeaveIndexes = dataSet.hashTree.diffHashes(receivedHashes);
|
|
1122
|
-
mismatchedLeaveIndexes.forEach(function (index) {
|
|
1123
|
-
mismatchedLeavesData[index] = dataSet.hashTree.getLeafData(index);
|
|
1124
|
-
});
|
|
1125
|
-
_context8.next = 8;
|
|
1126
|
-
break;
|
|
1127
|
-
case 7:
|
|
1128
|
-
mismatchedLeavesData[0] = dataSet.hashTree.getLeafData(0);
|
|
1129
|
-
case 8:
|
|
1130
|
-
if (!((0, _keys.default)(mismatchedLeavesData).length > 0)) {
|
|
1131
|
-
_context8.next = 10;
|
|
1132
|
-
break;
|
|
1133
|
-
}
|
|
1134
|
-
_context8.next = 9;
|
|
1135
|
-
return _this8.sendSyncRequestToLocus(dataSet, mismatchedLeavesData);
|
|
1136
|
-
case 9:
|
|
1137
|
-
syncResponse = _context8.sent;
|
|
1138
|
-
// sync API may return nothing (in that case data will arrive via messages)
|
|
1139
|
-
// or it may return a response in the same format as messages
|
|
1140
|
-
if (syncResponse) {
|
|
1141
|
-
_this8.handleMessage(syncResponse, 'via sync API');
|
|
1142
|
-
}
|
|
1143
|
-
case 10:
|
|
1144
|
-
_context8.next = 12;
|
|
1145
|
-
break;
|
|
1146
|
-
case 11:
|
|
1147
|
-
_loggerProxy.default.logger.info("HashTreeParser#runSyncAlgorithm --> ".concat(_this8.debugId, " \"").concat(dataSet.name, "\" root hash matching: ").concat(rootHash, ", version=").concat(dataSet.version));
|
|
1148
|
-
case 12:
|
|
1149
1396
|
case "end":
|
|
1150
|
-
return
|
|
1397
|
+
return _context7.stop();
|
|
1151
1398
|
}
|
|
1152
|
-
},
|
|
1399
|
+
}, _callee6);
|
|
1153
1400
|
})), delay);
|
|
1154
1401
|
} else {
|
|
1155
1402
|
_loggerProxy.default.logger.info("HashTreeParser#runSyncAlgorithm --> ".concat(this.debugId, " No delay for \"").concat(dataSet.name, "\" data set, skipping sync timer reset/setup"));
|
|
1156
1403
|
}
|
|
1157
1404
|
}
|
|
1158
1405
|
|
|
1406
|
+
/**
|
|
1407
|
+
* Resets the heartbeat watchdog timers for the specified data sets. Each data set has its own
|
|
1408
|
+
* watchdog timer that monitors whether heartbeats are being received within the expected interval.
|
|
1409
|
+
* If a heartbeat is not received for a specific data set within heartbeatIntervalMs plus
|
|
1410
|
+
* a backoff-calculated time, the sync algorithm is initiated for that data set
|
|
1411
|
+
*
|
|
1412
|
+
* @param {Array<DataSet>} receivedDataSets - The data sets from the received message for which watchdog timers should be reset
|
|
1413
|
+
* @returns {void}
|
|
1414
|
+
*/
|
|
1415
|
+
}, {
|
|
1416
|
+
key: "resetHeartbeatWatchdogs",
|
|
1417
|
+
value: function resetHeartbeatWatchdogs(receivedDataSets) {
|
|
1418
|
+
var _this12 = this;
|
|
1419
|
+
if (!this.heartbeatIntervalMs) {
|
|
1420
|
+
return;
|
|
1421
|
+
}
|
|
1422
|
+
var _iterator9 = _createForOfIteratorHelper(receivedDataSets),
|
|
1423
|
+
_step9;
|
|
1424
|
+
try {
|
|
1425
|
+
var _loop2 = function _loop2() {
|
|
1426
|
+
var receivedDataSet = _step9.value;
|
|
1427
|
+
var dataSet = _this12.dataSets[receivedDataSet.name];
|
|
1428
|
+
if (!(dataSet !== null && dataSet !== void 0 && dataSet.hashTree)) {
|
|
1429
|
+
// eslint-disable-next-line no-continue
|
|
1430
|
+
return 1; // continue
|
|
1431
|
+
}
|
|
1432
|
+
if (dataSet.heartbeatWatchdogTimer) {
|
|
1433
|
+
clearTimeout(dataSet.heartbeatWatchdogTimer);
|
|
1434
|
+
dataSet.heartbeatWatchdogTimer = undefined;
|
|
1435
|
+
}
|
|
1436
|
+
var backoffTime = _this12.getWeightedBackoffTime(dataSet.backoff);
|
|
1437
|
+
var delay = _this12.heartbeatIntervalMs + backoffTime;
|
|
1438
|
+
dataSet.heartbeatWatchdogTimer = setTimeout(/*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee7() {
|
|
1439
|
+
return _regenerator.default.wrap(function (_context8) {
|
|
1440
|
+
while (1) switch (_context8.prev = _context8.next) {
|
|
1441
|
+
case 0:
|
|
1442
|
+
dataSet.heartbeatWatchdogTimer = undefined;
|
|
1443
|
+
_loggerProxy.default.logger.warn("HashTreeParser#resetHeartbeatWatchdogs --> ".concat(_this12.debugId, " Heartbeat watchdog fired for data set \"").concat(dataSet.name, "\" - no heartbeat received within expected interval, initiating sync"));
|
|
1444
|
+
_context8.next = 1;
|
|
1445
|
+
return _this12.performSync(dataSet, dataSet.hashTree.getRootHash(), "heartbeat watchdog expired");
|
|
1446
|
+
case 1:
|
|
1447
|
+
case "end":
|
|
1448
|
+
return _context8.stop();
|
|
1449
|
+
}
|
|
1450
|
+
}, _callee7);
|
|
1451
|
+
})), delay);
|
|
1452
|
+
};
|
|
1453
|
+
for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
|
|
1454
|
+
if (_loop2()) continue;
|
|
1455
|
+
}
|
|
1456
|
+
} catch (err) {
|
|
1457
|
+
_iterator9.e(err);
|
|
1458
|
+
} finally {
|
|
1459
|
+
_iterator9.f();
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1159
1463
|
/**
|
|
1160
1464
|
* Stops all timers for the data sets to prevent any further sync attempts.
|
|
1161
1465
|
* @returns {void}
|
|
@@ -1168,39 +1472,59 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1168
1472
|
clearTimeout(dataSet.timer);
|
|
1169
1473
|
dataSet.timer = undefined;
|
|
1170
1474
|
}
|
|
1475
|
+
if (dataSet.heartbeatWatchdogTimer) {
|
|
1476
|
+
clearTimeout(dataSet.heartbeatWatchdogTimer);
|
|
1477
|
+
dataSet.heartbeatWatchdogTimer = undefined;
|
|
1478
|
+
}
|
|
1171
1479
|
});
|
|
1172
1480
|
}
|
|
1481
|
+
}, {
|
|
1482
|
+
key: "checkForSentinelHttpResponse",
|
|
1483
|
+
value: function checkForSentinelHttpResponse(error, dataSetName) {
|
|
1484
|
+
var _error$body;
|
|
1485
|
+
var isValidDataSetForSentinel = dataSetName === undefined || PossibleSentinelMessageDataSetNames.includes(dataSetName.toLowerCase());
|
|
1486
|
+
if ((error.statusCode === 409 && ((_error$body = error.body) === null || _error$body === void 0 ? void 0 : _error$body.errorCode) === 2403004 || error.statusCode === 404) && isValidDataSetForSentinel) {
|
|
1487
|
+
_loggerProxy.default.logger.info("HashTreeParser#checkForSentinelHttpResponse --> ".concat(this.debugId, " Received ").concat(error.statusCode, " for data set \"").concat(dataSetName, "\", indicating that the meeting has ended"));
|
|
1488
|
+
this.stopAllTimers();
|
|
1489
|
+
throw new MeetingEndedError();
|
|
1490
|
+
}
|
|
1491
|
+
}
|
|
1173
1492
|
|
|
1174
1493
|
/**
|
|
1175
1494
|
* Gets the current hashes from the locus for a specific data set.
|
|
1176
1495
|
* @param {string} dataSetName
|
|
1496
|
+
* @param {string} currentRootHash
|
|
1177
1497
|
* @returns {string[]}
|
|
1178
1498
|
*/
|
|
1179
1499
|
}, {
|
|
1180
1500
|
key: "getHashesFromLocus",
|
|
1181
|
-
value: function getHashesFromLocus(dataSetName) {
|
|
1182
|
-
var
|
|
1501
|
+
value: function getHashesFromLocus(dataSetName, currentRootHash) {
|
|
1502
|
+
var _this13 = this;
|
|
1183
1503
|
_loggerProxy.default.logger.info("HashTreeParser#getHashesFromLocus --> ".concat(this.debugId, " Requesting hashes for data set \"").concat(dataSetName, "\""));
|
|
1184
1504
|
var dataSet = this.dataSets[dataSetName];
|
|
1185
1505
|
var url = "".concat(dataSet.url, "/hashtree");
|
|
1186
1506
|
return this.webexRequest({
|
|
1187
1507
|
method: _constants.HTTP_VERBS.GET,
|
|
1188
|
-
uri: url
|
|
1508
|
+
uri: url,
|
|
1509
|
+
qs: {
|
|
1510
|
+
rootHash: currentRootHash
|
|
1511
|
+
}
|
|
1189
1512
|
}).then(function (response) {
|
|
1190
1513
|
var _response$body, _response$body2;
|
|
1191
1514
|
var hashes = (_response$body = response.body) === null || _response$body === void 0 ? void 0 : _response$body.hashes;
|
|
1192
1515
|
var dataSetFromResponse = (_response$body2 = response.body) === null || _response$body2 === void 0 ? void 0 : _response$body2.dataSet;
|
|
1193
1516
|
if (!hashes || !(0, _isArray.default)(hashes)) {
|
|
1194
|
-
_loggerProxy.default.logger.warn("HashTreeParser#getHashesFromLocus --> ".concat(
|
|
1517
|
+
_loggerProxy.default.logger.warn("HashTreeParser#getHashesFromLocus --> ".concat(_this13.debugId, " Locus returned invalid hashes, response body="), response.body);
|
|
1195
1518
|
throw new Error("Locus returned invalid hashes: ".concat(hashes));
|
|
1196
1519
|
}
|
|
1197
|
-
_loggerProxy.default.logger.info("HashTreeParser#getHashesFromLocus --> ".concat(
|
|
1520
|
+
_loggerProxy.default.logger.info("HashTreeParser#getHashesFromLocus --> ".concat(_this13.debugId, " Received hashes for data set \"").concat(dataSetName, "\": ").concat((0, _stringify.default)(hashes)));
|
|
1198
1521
|
return {
|
|
1199
1522
|
hashes: hashes,
|
|
1200
1523
|
dataSet: dataSetFromResponse
|
|
1201
1524
|
};
|
|
1202
1525
|
}).catch(function (error) {
|
|
1203
|
-
_loggerProxy.default.logger.error("HashTreeParser#getHashesFromLocus --> ".concat(
|
|
1526
|
+
_loggerProxy.default.logger.error("HashTreeParser#getHashesFromLocus --> ".concat(_this13.debugId, " Error ").concat(error.statusCode, " fetching hashes for data set \"").concat(dataSetName, "\":"), error);
|
|
1527
|
+
_this13.checkForSentinelHttpResponse(error, dataSet.name);
|
|
1204
1528
|
throw error;
|
|
1205
1529
|
});
|
|
1206
1530
|
}
|
|
@@ -1215,7 +1539,7 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1215
1539
|
}, {
|
|
1216
1540
|
key: "sendSyncRequestToLocus",
|
|
1217
1541
|
value: function sendSyncRequestToLocus(dataSet, mismatchedLeavesData) {
|
|
1218
|
-
var
|
|
1542
|
+
var _this14 = this;
|
|
1219
1543
|
_loggerProxy.default.logger.info("HashTreeParser#sendSyncRequestToLocus --> ".concat(this.debugId, " Sending sync request for data set \"").concat(dataSet.name, "\""));
|
|
1220
1544
|
var url = "".concat(dataSet.url, "/sync");
|
|
1221
1545
|
var body = {
|
|
@@ -1228,19 +1552,24 @@ var HashTreeParser = /*#__PURE__*/function () {
|
|
|
1228
1552
|
elementIds: mismatchedLeavesData[index]
|
|
1229
1553
|
});
|
|
1230
1554
|
});
|
|
1555
|
+
var ourCurrentRootHash = dataSet.hashTree ? dataSet.hashTree.getRootHash() : _constants2.EMPTY_HASH;
|
|
1231
1556
|
return this.webexRequest({
|
|
1232
1557
|
method: _constants.HTTP_VERBS.POST,
|
|
1233
1558
|
uri: url,
|
|
1559
|
+
qs: {
|
|
1560
|
+
rootHash: ourCurrentRootHash
|
|
1561
|
+
},
|
|
1234
1562
|
body: body
|
|
1235
1563
|
}).then(function (resp) {
|
|
1236
|
-
_loggerProxy.default.logger.info("HashTreeParser#sendSyncRequestToLocus --> ".concat(
|
|
1564
|
+
_loggerProxy.default.logger.info("HashTreeParser#sendSyncRequestToLocus --> ".concat(_this14.debugId, " Sync request succeeded for \"").concat(dataSet.name, "\""));
|
|
1237
1565
|
if (!resp.body || (0, _lodash.isEmpty)(resp.body)) {
|
|
1238
|
-
_loggerProxy.default.logger.info("HashTreeParser#sendSyncRequestToLocus --> ".concat(
|
|
1566
|
+
_loggerProxy.default.logger.info("HashTreeParser#sendSyncRequestToLocus --> ".concat(_this14.debugId, " Got ").concat(resp.statusCode, " with empty body for sync request for data set \"").concat(dataSet.name, "\", data should arrive via messages"));
|
|
1239
1567
|
return null;
|
|
1240
1568
|
}
|
|
1241
1569
|
return resp.body;
|
|
1242
1570
|
}).catch(function (error) {
|
|
1243
|
-
_loggerProxy.default.logger.error("HashTreeParser#sendSyncRequestToLocus --> ".concat(
|
|
1571
|
+
_loggerProxy.default.logger.error("HashTreeParser#sendSyncRequestToLocus --> ".concat(_this14.debugId, " Error ").concat(error.statusCode, " sending sync request for data set \"").concat(dataSet.name, "\":"), error);
|
|
1572
|
+
_this14.checkForSentinelHttpResponse(error, dataSet.name);
|
|
1244
1573
|
throw error;
|
|
1245
1574
|
});
|
|
1246
1575
|
}
|