@webex/plugin-meetings 3.4.0-next.5 → 3.4.0-next.6
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/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/reachability/index.js +146 -93
- package/dist/reachability/index.js.map +1 -1
- package/dist/types/reachability/index.d.ts +11 -1
- package/dist/webinar/index.js +1 -1
- package/package.json +3 -3
- package/src/reachability/index.ts +27 -3
- package/test/unit/spec/reachability/index.ts +65 -2
package/dist/breakouts/index.js
CHANGED
|
@@ -1046,7 +1046,7 @@ var Breakouts = _webexCore.WebexPlugin.extend({
|
|
|
1046
1046
|
this.trigger(_constants.BREAKOUTS.EVENTS.ASK_RETURN_TO_MAIN);
|
|
1047
1047
|
}
|
|
1048
1048
|
},
|
|
1049
|
-
version: "3.4.0-next.
|
|
1049
|
+
version: "3.4.0-next.6"
|
|
1050
1050
|
});
|
|
1051
1051
|
var _default = exports.default = Breakouts;
|
|
1052
1052
|
//# sourceMappingURL=index.js.map
|
|
@@ -373,7 +373,7 @@ var SimultaneousInterpretation = _webexCore.WebexPlugin.extend({
|
|
|
373
373
|
throw error;
|
|
374
374
|
});
|
|
375
375
|
},
|
|
376
|
-
version: "3.4.0-next.
|
|
376
|
+
version: "3.4.0-next.6"
|
|
377
377
|
});
|
|
378
378
|
var _default = exports.default = SimultaneousInterpretation;
|
|
379
379
|
//# sourceMappingURL=index.js.map
|
|
@@ -12,11 +12,11 @@ _Object$defineProperty(exports, "__esModule", {
|
|
|
12
12
|
value: true
|
|
13
13
|
});
|
|
14
14
|
exports.default = void 0;
|
|
15
|
-
var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));
|
|
16
15
|
var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
|
|
17
16
|
var _values = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/values"));
|
|
18
17
|
var _entries = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/entries"));
|
|
19
18
|
var _keys = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/keys"));
|
|
19
|
+
var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));
|
|
20
20
|
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/toConsumableArray"));
|
|
21
21
|
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/slicedToArray"));
|
|
22
22
|
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/asyncToGenerator"));
|
|
@@ -116,46 +116,99 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
|
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
/**
|
|
119
|
-
*
|
|
120
|
-
* @
|
|
121
|
-
* @
|
|
122
|
-
* @
|
|
119
|
+
* Fetches the list of media clusters from the backend
|
|
120
|
+
* @param {boolean} isRetry
|
|
121
|
+
* @private
|
|
122
|
+
* @returns {Promise<{clusters: ClusterList, joinCookie: any}>}
|
|
123
123
|
*/
|
|
124
124
|
(0, _createClass2.default)(Reachability, [{
|
|
125
|
-
key: "
|
|
125
|
+
key: "getClusters",
|
|
126
126
|
value: (function () {
|
|
127
|
-
var
|
|
128
|
-
var
|
|
127
|
+
var _getClusters = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
|
|
128
|
+
var isRetry,
|
|
129
|
+
_yield$this$reachabil,
|
|
130
|
+
clusters,
|
|
131
|
+
joinCookie,
|
|
132
|
+
_args = arguments;
|
|
129
133
|
return _regenerator.default.wrap(function _callee$(_context) {
|
|
130
134
|
while (1) switch (_context.prev = _context.next) {
|
|
131
135
|
case 0:
|
|
132
|
-
|
|
133
|
-
_context.
|
|
136
|
+
isRetry = _args.length > 0 && _args[0] !== undefined ? _args[0] : false;
|
|
137
|
+
_context.prev = 1;
|
|
138
|
+
_context.next = 4;
|
|
134
139
|
return this.reachabilityRequest.getClusters(_util.default.getIpVersion(this.webex));
|
|
135
|
-
case
|
|
140
|
+
case 4:
|
|
136
141
|
_yield$this$reachabil = _context.sent;
|
|
137
142
|
clusters = _yield$this$reachabil.clusters;
|
|
138
143
|
joinCookie = _yield$this$reachabil.joinCookie;
|
|
139
|
-
_context.
|
|
144
|
+
return _context.abrupt("return", {
|
|
145
|
+
clusters: clusters,
|
|
146
|
+
joinCookie: joinCookie
|
|
147
|
+
});
|
|
148
|
+
case 10:
|
|
149
|
+
_context.prev = 10;
|
|
150
|
+
_context.t0 = _context["catch"](1);
|
|
151
|
+
if (!isRetry) {
|
|
152
|
+
_context.next = 14;
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
throw _context.t0;
|
|
156
|
+
case 14:
|
|
157
|
+
_loggerProxy.default.logger.error("Reachability:index#getClusters --> Failed with error: ".concat(_context.t0, ", retrying..."));
|
|
158
|
+
return _context.abrupt("return", this.getClusters(true));
|
|
159
|
+
case 16:
|
|
160
|
+
case "end":
|
|
161
|
+
return _context.stop();
|
|
162
|
+
}
|
|
163
|
+
}, _callee, this, [[1, 10]]);
|
|
164
|
+
}));
|
|
165
|
+
function getClusters() {
|
|
166
|
+
return _getClusters.apply(this, arguments);
|
|
167
|
+
}
|
|
168
|
+
return getClusters;
|
|
169
|
+
}()
|
|
170
|
+
/**
|
|
171
|
+
* Gets a list of media clusters from the backend and performs reachability checks on all the clusters
|
|
172
|
+
* @returns {Promise<ReachabilityResults>} reachability results
|
|
173
|
+
* @public
|
|
174
|
+
* @memberof Reachability
|
|
175
|
+
*/
|
|
176
|
+
)
|
|
177
|
+
}, {
|
|
178
|
+
key: "gatherReachability",
|
|
179
|
+
value: (function () {
|
|
180
|
+
var _gatherReachability = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
|
|
181
|
+
var _yield$this$getCluste, clusters, joinCookie;
|
|
182
|
+
return _regenerator.default.wrap(function _callee2$(_context2) {
|
|
183
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
184
|
+
case 0:
|
|
185
|
+
_context2.prev = 0;
|
|
186
|
+
_context2.next = 3;
|
|
187
|
+
return this.getClusters();
|
|
188
|
+
case 3:
|
|
189
|
+
_yield$this$getCluste = _context2.sent;
|
|
190
|
+
clusters = _yield$this$getCluste.clusters;
|
|
191
|
+
joinCookie = _yield$this$getCluste.joinCookie;
|
|
192
|
+
_context2.next = 8;
|
|
140
193
|
return this.webex.boundedStorage.put(this.namespace, _constants.REACHABILITY.localStorageJoinCookie, (0, _stringify.default)(joinCookie));
|
|
141
194
|
case 8:
|
|
142
195
|
this.reachabilityDefer = new _common.Defer();
|
|
143
196
|
|
|
144
197
|
// Perform Reachability Check
|
|
145
|
-
|
|
198
|
+
_context2.next = 11;
|
|
146
199
|
return this.performReachabilityChecks(clusters);
|
|
147
200
|
case 11:
|
|
148
|
-
return
|
|
201
|
+
return _context2.abrupt("return", this.reachabilityDefer.promise);
|
|
149
202
|
case 14:
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
_loggerProxy.default.logger.error("Reachability:index#gatherReachability --> Error:",
|
|
153
|
-
return
|
|
203
|
+
_context2.prev = 14;
|
|
204
|
+
_context2.t0 = _context2["catch"](0);
|
|
205
|
+
_loggerProxy.default.logger.error("Reachability:index#gatherReachability --> Error:", _context2.t0);
|
|
206
|
+
return _context2.abrupt("return", {});
|
|
154
207
|
case 18:
|
|
155
208
|
case "end":
|
|
156
|
-
return
|
|
209
|
+
return _context2.stop();
|
|
157
210
|
}
|
|
158
|
-
},
|
|
211
|
+
}, _callee2, this, [[0, 14]]);
|
|
159
212
|
}));
|
|
160
213
|
function gatherReachability() {
|
|
161
214
|
return _gatherReachability.apply(this, arguments);
|
|
@@ -172,10 +225,10 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
|
|
|
172
225
|
}, {
|
|
173
226
|
key: "getReachabilityMetrics",
|
|
174
227
|
value: (function () {
|
|
175
|
-
var _getReachabilityMetrics = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function
|
|
228
|
+
var _getReachabilityMetrics = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() {
|
|
176
229
|
var stats, updateStats, resultsJson, results;
|
|
177
|
-
return _regenerator.default.wrap(function
|
|
178
|
-
while (1) switch (
|
|
230
|
+
return _regenerator.default.wrap(function _callee3$(_context3) {
|
|
231
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
179
232
|
case 0:
|
|
180
233
|
stats = {
|
|
181
234
|
reachability_public_udp_success: 0,
|
|
@@ -205,29 +258,29 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
|
|
|
205
258
|
stats["reachability_".concat(clusterType, "_xtls_").concat(_outcome2)] += 1;
|
|
206
259
|
}
|
|
207
260
|
};
|
|
208
|
-
|
|
209
|
-
|
|
261
|
+
_context3.prev = 2;
|
|
262
|
+
_context3.next = 5;
|
|
210
263
|
return this.webex.boundedStorage.get(_constants.REACHABILITY.namespace, _constants.REACHABILITY.localStorageResult);
|
|
211
264
|
case 5:
|
|
212
|
-
resultsJson =
|
|
265
|
+
resultsJson = _context3.sent;
|
|
213
266
|
results = JSON.parse(resultsJson);
|
|
214
267
|
(0, _values.default)(results).forEach(function (result) {
|
|
215
268
|
updateStats(result.isVideoMesh ? 'vmn' : 'public', result);
|
|
216
269
|
});
|
|
217
|
-
|
|
270
|
+
_context3.next = 13;
|
|
218
271
|
break;
|
|
219
272
|
case 10:
|
|
220
|
-
|
|
221
|
-
|
|
273
|
+
_context3.prev = 10;
|
|
274
|
+
_context3.t0 = _context3["catch"](2);
|
|
222
275
|
// empty storage, that's ok
|
|
223
|
-
_loggerProxy.default.logger.warn('Roap:request#getReachabilityMetrics --> Error parsing reachability data: ',
|
|
276
|
+
_loggerProxy.default.logger.warn('Roap:request#getReachabilityMetrics --> Error parsing reachability data: ', _context3.t0);
|
|
224
277
|
case 13:
|
|
225
|
-
return
|
|
278
|
+
return _context3.abrupt("return", stats);
|
|
226
279
|
case 14:
|
|
227
280
|
case "end":
|
|
228
|
-
return
|
|
281
|
+
return _context3.stop();
|
|
229
282
|
}
|
|
230
|
-
},
|
|
283
|
+
}, _callee3, this, [[2, 10]]);
|
|
231
284
|
}));
|
|
232
285
|
function getReachabilityMetrics() {
|
|
233
286
|
return _getReachabilityMetrics.apply(this, arguments);
|
|
@@ -280,17 +333,17 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
|
|
|
280
333
|
}, {
|
|
281
334
|
key: "getReachabilityResults",
|
|
282
335
|
value: (function () {
|
|
283
|
-
var _getReachabilityResults = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function
|
|
336
|
+
var _getReachabilityResults = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4() {
|
|
284
337
|
var _this2 = this;
|
|
285
338
|
var results, resultsJson, allClusterResults;
|
|
286
|
-
return _regenerator.default.wrap(function
|
|
287
|
-
while (1) switch (
|
|
339
|
+
return _regenerator.default.wrap(function _callee4$(_context4) {
|
|
340
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
288
341
|
case 0:
|
|
289
|
-
|
|
290
|
-
|
|
342
|
+
_context4.prev = 0;
|
|
343
|
+
_context4.next = 3;
|
|
291
344
|
return this.webex.boundedStorage.get(_constants.REACHABILITY.namespace, _constants.REACHABILITY.localStorageResult);
|
|
292
345
|
case 3:
|
|
293
|
-
resultsJson =
|
|
346
|
+
resultsJson = _context4.sent;
|
|
294
347
|
allClusterResults = JSON.parse(resultsJson);
|
|
295
348
|
results = (0, _lodash.mapValues)(allClusterResults, function (clusterResult) {
|
|
296
349
|
return {
|
|
@@ -305,20 +358,20 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
|
|
|
305
358
|
})
|
|
306
359
|
};
|
|
307
360
|
});
|
|
308
|
-
|
|
361
|
+
_context4.next = 11;
|
|
309
362
|
break;
|
|
310
363
|
case 8:
|
|
311
|
-
|
|
312
|
-
|
|
364
|
+
_context4.prev = 8;
|
|
365
|
+
_context4.t0 = _context4["catch"](0);
|
|
313
366
|
// empty storage, that's ok
|
|
314
|
-
_loggerProxy.default.logger.warn('Roap:request#attachReachabilityData --> Error parsing reachability data: ',
|
|
367
|
+
_loggerProxy.default.logger.warn('Roap:request#attachReachabilityData --> Error parsing reachability data: ', _context4.t0);
|
|
315
368
|
case 11:
|
|
316
|
-
return
|
|
369
|
+
return _context4.abrupt("return", results);
|
|
317
370
|
case 12:
|
|
318
371
|
case "end":
|
|
319
|
-
return
|
|
372
|
+
return _context4.stop();
|
|
320
373
|
}
|
|
321
|
-
},
|
|
374
|
+
}, _callee4, this, [[0, 8]]);
|
|
322
375
|
}));
|
|
323
376
|
function getReachabilityResults() {
|
|
324
377
|
return _getReachabilityResults.apply(this, arguments);
|
|
@@ -335,16 +388,16 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
|
|
|
335
388
|
}, {
|
|
336
389
|
key: "isAnyPublicClusterReachable",
|
|
337
390
|
value: (function () {
|
|
338
|
-
var _isAnyPublicClusterReachable = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function
|
|
391
|
+
var _isAnyPublicClusterReachable = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5() {
|
|
339
392
|
var reachable, reachabilityData, reachabilityResults;
|
|
340
|
-
return _regenerator.default.wrap(function
|
|
341
|
-
while (1) switch (
|
|
393
|
+
return _regenerator.default.wrap(function _callee5$(_context5) {
|
|
394
|
+
while (1) switch (_context5.prev = _context5.next) {
|
|
342
395
|
case 0:
|
|
343
396
|
reachable = false; // @ts-ignore
|
|
344
|
-
|
|
397
|
+
_context5.next = 3;
|
|
345
398
|
return this.webex.boundedStorage.get(this.namespace, _constants.REACHABILITY.localStorageResult).catch(function () {});
|
|
346
399
|
case 3:
|
|
347
|
-
reachabilityData =
|
|
400
|
+
reachabilityData = _context5.sent;
|
|
348
401
|
if (reachabilityData) {
|
|
349
402
|
try {
|
|
350
403
|
reachabilityResults = JSON.parse(reachabilityData);
|
|
@@ -356,12 +409,12 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
|
|
|
356
409
|
_loggerProxy.default.logger.error("Roap:request#attachReachabilityData --> Error in parsing reachability data: ".concat(e));
|
|
357
410
|
}
|
|
358
411
|
}
|
|
359
|
-
return
|
|
412
|
+
return _context5.abrupt("return", reachable);
|
|
360
413
|
case 6:
|
|
361
414
|
case "end":
|
|
362
|
-
return
|
|
415
|
+
return _context5.stop();
|
|
363
416
|
}
|
|
364
|
-
},
|
|
417
|
+
}, _callee5, this);
|
|
365
418
|
}));
|
|
366
419
|
function isAnyPublicClusterReachable() {
|
|
367
420
|
return _isAnyPublicClusterReachable.apply(this, arguments);
|
|
@@ -382,16 +435,16 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
|
|
|
382
435
|
}, {
|
|
383
436
|
key: "isWebexMediaBackendUnreachable",
|
|
384
437
|
value: (function () {
|
|
385
|
-
var _isWebexMediaBackendUnreachable = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function
|
|
438
|
+
var _isWebexMediaBackendUnreachable = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6() {
|
|
386
439
|
var unreachable, reachabilityData, reachabilityResults, protocols;
|
|
387
|
-
return _regenerator.default.wrap(function
|
|
388
|
-
while (1) switch (
|
|
440
|
+
return _regenerator.default.wrap(function _callee6$(_context6) {
|
|
441
|
+
while (1) switch (_context6.prev = _context6.next) {
|
|
389
442
|
case 0:
|
|
390
443
|
unreachable = false; // @ts-ignore
|
|
391
|
-
|
|
444
|
+
_context6.next = 3;
|
|
392
445
|
return this.webex.boundedStorage.get(this.namespace, _constants.REACHABILITY.localStorageResult).catch(function () {});
|
|
393
446
|
case 3:
|
|
394
|
-
reachabilityData =
|
|
447
|
+
reachabilityData = _context6.sent;
|
|
395
448
|
if (reachabilityData) {
|
|
396
449
|
try {
|
|
397
450
|
reachabilityResults = JSON.parse(reachabilityData);
|
|
@@ -429,12 +482,12 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
|
|
|
429
482
|
_loggerProxy.default.logger.error("Roap:request#attachReachabilityData --> Error in parsing reachability data: ".concat(e));
|
|
430
483
|
}
|
|
431
484
|
}
|
|
432
|
-
return
|
|
485
|
+
return _context6.abrupt("return", unreachable);
|
|
433
486
|
case 6:
|
|
434
487
|
case "end":
|
|
435
|
-
return
|
|
488
|
+
return _context6.stop();
|
|
436
489
|
}
|
|
437
|
-
},
|
|
490
|
+
}, _callee6, this);
|
|
438
491
|
}));
|
|
439
492
|
function isWebexMediaBackendUnreachable() {
|
|
440
493
|
return _isWebexMediaBackendUnreachable.apply(this, arguments);
|
|
@@ -591,10 +644,10 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
|
|
|
591
644
|
}, {
|
|
592
645
|
key: "sendMetric",
|
|
593
646
|
value: (function () {
|
|
594
|
-
var _sendMetric = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function
|
|
647
|
+
var _sendMetric = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7() {
|
|
595
648
|
var results, stats;
|
|
596
|
-
return _regenerator.default.wrap(function
|
|
597
|
-
while (1) switch (
|
|
649
|
+
return _regenerator.default.wrap(function _callee7$(_context7) {
|
|
650
|
+
while (1) switch (_context7.prev = _context7.next) {
|
|
598
651
|
case 0:
|
|
599
652
|
results = [];
|
|
600
653
|
(0, _values.default)(this.clusterReachability).forEach(function (clusterReachability) {
|
|
@@ -615,9 +668,9 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
|
|
|
615
668
|
_metrics.default.sendBehavioralMetric(_constants2.default.REACHABILITY_COMPLETED, _metrics.default.prepareMetricFields(stats));
|
|
616
669
|
case 4:
|
|
617
670
|
case "end":
|
|
618
|
-
return
|
|
671
|
+
return _context7.stop();
|
|
619
672
|
}
|
|
620
|
-
},
|
|
673
|
+
}, _callee7, this);
|
|
621
674
|
}));
|
|
622
675
|
function sendMetric() {
|
|
623
676
|
return _sendMetric.apply(this, arguments);
|
|
@@ -671,17 +724,17 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
|
|
|
671
724
|
}, {
|
|
672
725
|
key: "storeResults",
|
|
673
726
|
value: (function () {
|
|
674
|
-
var _storeResults = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function
|
|
675
|
-
return _regenerator.default.wrap(function
|
|
676
|
-
while (1) switch (
|
|
727
|
+
var _storeResults = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee8(results) {
|
|
728
|
+
return _regenerator.default.wrap(function _callee8$(_context8) {
|
|
729
|
+
while (1) switch (_context8.prev = _context8.next) {
|
|
677
730
|
case 0:
|
|
678
|
-
|
|
731
|
+
_context8.next = 2;
|
|
679
732
|
return this.webex.boundedStorage.put(this.namespace, _constants.REACHABILITY.localStorageResult, (0, _stringify.default)(results));
|
|
680
733
|
case 2:
|
|
681
734
|
case "end":
|
|
682
|
-
return
|
|
735
|
+
return _context8.stop();
|
|
683
736
|
}
|
|
684
|
-
},
|
|
737
|
+
}, _callee8, this);
|
|
685
738
|
}));
|
|
686
739
|
function storeResults(_x) {
|
|
687
740
|
return _storeResults.apply(this, arguments);
|
|
@@ -715,19 +768,19 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
|
|
|
715
768
|
}, {
|
|
716
769
|
key: "performReachabilityChecks",
|
|
717
770
|
value: (function () {
|
|
718
|
-
var _performReachabilityChecks = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function
|
|
771
|
+
var _performReachabilityChecks = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee11(clusterList) {
|
|
719
772
|
var _this4 = this;
|
|
720
773
|
var results, isFirstResult;
|
|
721
|
-
return _regenerator.default.wrap(function
|
|
722
|
-
while (1) switch (
|
|
774
|
+
return _regenerator.default.wrap(function _callee11$(_context11) {
|
|
775
|
+
while (1) switch (_context11.prev = _context11.next) {
|
|
723
776
|
case 0:
|
|
724
777
|
results = {};
|
|
725
778
|
this.clusterReachability = {};
|
|
726
779
|
if (!(!clusterList || !(0, _keys.default)(clusterList).length)) {
|
|
727
|
-
|
|
780
|
+
_context11.next = 4;
|
|
728
781
|
break;
|
|
729
782
|
}
|
|
730
|
-
return
|
|
783
|
+
return _context11.abrupt("return");
|
|
731
784
|
case 4:
|
|
732
785
|
_loggerProxy.default.logger.log("Reachability:index#performReachabilityChecks --> doing UDP".concat(
|
|
733
786
|
// @ts-ignore
|
|
@@ -783,7 +836,7 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
|
|
|
783
836
|
tcp: true,
|
|
784
837
|
xtls: true
|
|
785
838
|
}; // save the initialized results (in case we don't get any "resultReady" events at all)
|
|
786
|
-
|
|
839
|
+
_context11.next = 11;
|
|
787
840
|
return this.storeResults(results);
|
|
788
841
|
case 11:
|
|
789
842
|
// now start the reachability on all the clusters
|
|
@@ -791,10 +844,10 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
|
|
|
791
844
|
var cluster = clusterList[key];
|
|
792
845
|
_this4.clusterReachability[key] = new _clusterReachability.ClusterReachability(key, cluster);
|
|
793
846
|
_this4.clusterReachability[key].on(_clusterReachability.Events.resultReady, /*#__PURE__*/function () {
|
|
794
|
-
var _ref4 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function
|
|
847
|
+
var _ref4 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee9(data) {
|
|
795
848
|
var protocol, result, clientMediaIPs, latencyInMilliseconds, areAllResultsReady;
|
|
796
|
-
return _regenerator.default.wrap(function
|
|
797
|
-
while (1) switch (
|
|
849
|
+
return _regenerator.default.wrap(function _callee9$(_context9) {
|
|
850
|
+
while (1) switch (_context9.prev = _context9.next) {
|
|
798
851
|
case 0:
|
|
799
852
|
protocol = data.protocol, result = data.result, clientMediaIPs = data.clientMediaIPs, latencyInMilliseconds = data.latencyInMilliseconds;
|
|
800
853
|
if (isFirstResult[protocol]) {
|
|
@@ -811,7 +864,7 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
|
|
|
811
864
|
results[key][protocol].result = result;
|
|
812
865
|
results[key][protocol].clientMediaIPs = clientMediaIPs;
|
|
813
866
|
results[key][protocol].latencyInMilliseconds = latencyInMilliseconds;
|
|
814
|
-
|
|
867
|
+
_context9.next = 9;
|
|
815
868
|
return _this4.storeResults(results);
|
|
816
869
|
case 9:
|
|
817
870
|
if (areAllResultsReady) {
|
|
@@ -827,9 +880,9 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
|
|
|
827
880
|
}
|
|
828
881
|
case 10:
|
|
829
882
|
case "end":
|
|
830
|
-
return
|
|
883
|
+
return _context9.stop();
|
|
831
884
|
}
|
|
832
|
-
},
|
|
885
|
+
}, _callee9);
|
|
833
886
|
}));
|
|
834
887
|
return function (_x3) {
|
|
835
888
|
return _ref4.apply(this, arguments);
|
|
@@ -838,18 +891,18 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
|
|
|
838
891
|
|
|
839
892
|
// clientMediaIps can be updated independently from the results, so we need to listen for them too
|
|
840
893
|
_this4.clusterReachability[key].on(_clusterReachability.Events.clientMediaIpsUpdated, /*#__PURE__*/function () {
|
|
841
|
-
var _ref5 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function
|
|
842
|
-
return _regenerator.default.wrap(function
|
|
843
|
-
while (1) switch (
|
|
894
|
+
var _ref5 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee10(data) {
|
|
895
|
+
return _regenerator.default.wrap(function _callee10$(_context10) {
|
|
896
|
+
while (1) switch (_context10.prev = _context10.next) {
|
|
844
897
|
case 0:
|
|
845
898
|
results[key][data.protocol].clientMediaIPs = data.clientMediaIPs;
|
|
846
|
-
|
|
899
|
+
_context10.next = 3;
|
|
847
900
|
return _this4.storeResults(results);
|
|
848
901
|
case 3:
|
|
849
902
|
case "end":
|
|
850
|
-
return
|
|
903
|
+
return _context10.stop();
|
|
851
904
|
}
|
|
852
|
-
},
|
|
905
|
+
}, _callee10);
|
|
853
906
|
}));
|
|
854
907
|
return function (_x4) {
|
|
855
908
|
return _ref5.apply(this, arguments);
|
|
@@ -859,9 +912,9 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
|
|
|
859
912
|
});
|
|
860
913
|
case 12:
|
|
861
914
|
case "end":
|
|
862
|
-
return
|
|
915
|
+
return _context11.stop();
|
|
863
916
|
}
|
|
864
|
-
},
|
|
917
|
+
}, _callee11, this);
|
|
865
918
|
}));
|
|
866
919
|
function performReachabilityChecks(_x2) {
|
|
867
920
|
return _performReachabilityChecks.apply(this, arguments);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_lodash","require","_common","_loggerProxy","_interopRequireDefault","_util","_constants","_request","_clusterReachability","_eventsScope","_constants2","_metrics","ownKeys","e","r","t","_Object$keys2","_Object$getOwnPropertySymbols","o","filter","_Object$getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","arguments","length","Object","forEach","_defineProperty2","default","_Object$getOwnPropertyDescriptors","_Object$defineProperties","_Object$defineProperty","_createSuper","Derived","hasNativeReflectConstruct","_isNativeReflectConstruct","_createSuperInternal","Super","_getPrototypeOf2","result","NewTarget","constructor","_Reflect$construct","_possibleConstructorReturn2","Reflect","sham","Proxy","Boolean","prototype","valueOf","call","DEFAULT_TIMEOUT","VIDEO_MESH_TIMEOUT","OVERALL_TIMEOUT","Reachability","exports","_EventsScope","_inherits2","_super","webex","_this","_classCallCheck2","_assertThisInitialized2","REACHABILITY","namespace","videoMesh","udp","public","tcp","xtls","reachabilityRequest","ReachabilityRequest","clusterReachability","_createClass2","key","value","_gatherReachability","_asyncToGenerator2","_regenerator","mark","_callee","_yield$this$reachabil","clusters","joinCookie","wrap","_callee$","_context","prev","next","getClusters","MeetingUtil","getIpVersion","sent","boundedStorage","put","localStorageJoinCookie","_stringify","reachabilityDefer","Defer","performReachabilityChecks","abrupt","promise","t0","LoggerProxy","logger","error","stop","gatherReachability","_getReachabilityMetrics","_callee2","stats","updateStats","resultsJson","results","_callee2$","_context2","reachability_public_udp_success","reachability_public_udp_failed","reachability_public_tcp_success","reachability_public_tcp_failed","reachability_public_xtls_success","reachability_public_xtls_failed","reachability_vmn_udp_success","reachability_vmn_udp_failed","reachability_vmn_tcp_success","reachability_vmn_tcp_failed","reachability_vmn_xtls_success","reachability_vmn_xtls_failed","clusterType","outcome","concat","get","localStorageResult","JSON","parse","_values","isVideoMesh","warn","getReachabilityMetrics","mapTransportResultToBackendDataFormat","transportResult","output","_i","_Object$entries","_entries","_Object$entries$_i","_slicedToArray2","reachable","untested","latencyInMilliseconds","toString","_getReachabilityResults","_callee3","_this2","allClusterResults","_callee3$","_context3","mapValues","clusterResult","getReachabilityResults","_isAnyPublicClusterReachable","_callee4","reachabilityData","reachabilityResults","_callee4$","_context4","catch","some","_result$udp","_result$tcp","isAnyPublicClusterReachable","_isWebexMediaBackendUnreachable","_callee5","unreachable","protocols","_callee5$","_context5","tested","undefined","_keys","protocol","_result$protocol","_result$protocol2","every","isWebexMediaBackendUnreachable","getUnreachableClusters","unreachableList","_ref","_ref2","getResult","name","logUnreachableClusters","list","_ref3","log","areAllPublicClusterResultsReady","isEqual","expectedResultsCount","resultsCount","areAllResultsReady","resolveReachabilityPromise","_this$reachabilityDef","vmnTimer","clearTimeout","publicCloudTimer","resolve","abortClusterReachability","abort","getStatistics","values","map","min","max","average","Math","_toConsumableArray2","mean","_sendMetric","_callee6","_callee6$","_context6","vmn","Metrics","sendBehavioralMetric","BEHAVIORAL_METRICS","REACHABILITY_COMPLETED","prepareMetricFields","sendMetric","startTimers","_this3","setTimeout","overallTimer","emit","file","function","_storeResults","_callee7","_callee7$","_context7","storeResults","_x","resetResultCounters","_performReachabilityChecks","_callee10","clusterList","_this4","isFirstResult","_callee10$","_context10","config","meetings","experimental","enableTcpReachability","enableTlsReachability","cluster","includeTcpReachability","includeTlsReachability","ClusterReachability","on","Events","resultReady","_ref4","_callee8","data","clientMediaIPs","_callee8$","_context8","_x3","clientMediaIpsUpdated","_ref5","_callee9","_callee9$","_context9","_x4","start","_x2","EventsScope"],"sources":["index.ts"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\n/* eslint-disable class-methods-use-this */\nimport {isEqual, mapValues, mean} from 'lodash';\n\nimport {Defer} from '@webex/common';\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport MeetingUtil from '../meeting/util';\n\nimport {REACHABILITY} from '../constants';\n\nimport ReachabilityRequest, {ClusterList} from './request';\nimport {\n ClientMediaIpsUpdatedEventData,\n ClusterReachability,\n ClusterReachabilityResult,\n Events,\n ResultEventData,\n TransportResult,\n} from './clusterReachability';\nimport EventsScope from '../common/events/events-scope';\nimport BEHAVIORAL_METRICS from '../metrics/constants';\nimport Metrics from '../metrics';\n\nexport type ReachabilityMetrics = {\n reachability_public_udp_success: number;\n reachability_public_udp_failed: number;\n reachability_public_tcp_success: number;\n reachability_public_tcp_failed: number;\n reachability_public_xtls_success: number;\n reachability_public_xtls_failed: number;\n reachability_vmn_udp_success: number;\n reachability_vmn_udp_failed: number;\n reachability_vmn_tcp_success: number;\n reachability_vmn_tcp_failed: number;\n reachability_vmn_xtls_success: number;\n reachability_vmn_xtls_failed: number;\n};\n\n/**\n * This is the type that matches what backend expects us to send to them. It is a bit weird, because\n * it uses strings instead of booleans and numbers, but that's what they require.\n */\nexport type TransportResultForBackend = {\n reachable?: 'true' | 'false';\n latencyInMilliseconds?: string;\n clientMediaIPs?: string[];\n untested?: 'true';\n};\n\nexport type ReachabilityResultForBackend = {\n udp: TransportResultForBackend;\n tcp: TransportResultForBackend;\n xtls: TransportResultForBackend;\n};\n\n// this is the type that is required by the backend when we send them reachability results\nexport type ReachabilityResultsForBackend = Record<string, ReachabilityResultForBackend>;\n\n// this is the type used by Reachability class internally and stored in local storage\nexport type ReachabilityResults = Record<\n string,\n ClusterReachabilityResult & {\n isVideoMesh?: boolean;\n }\n>;\n\n// timeouts in seconds\nconst DEFAULT_TIMEOUT = 3;\nconst VIDEO_MESH_TIMEOUT = 1;\nconst OVERALL_TIMEOUT = 15;\n\n/**\n * @class Reachability\n * @export\n */\nexport default class Reachability extends EventsScope {\n namespace = REACHABILITY.namespace;\n webex: object;\n reachabilityRequest: ReachabilityRequest;\n clusterReachability: {\n [key: string]: ClusterReachability;\n };\n\n reachabilityDefer?: Defer;\n\n vmnTimer?: ReturnType<typeof setTimeout>;\n publicCloudTimer?: ReturnType<typeof setTimeout>;\n overallTimer?: ReturnType<typeof setTimeout>;\n\n expectedResultsCount = {videoMesh: {udp: 0}, public: {udp: 0, tcp: 0, xtls: 0}};\n resultsCount = {videoMesh: {udp: 0}, public: {udp: 0, tcp: 0, xtls: 0}};\n\n /**\n * Creates an instance of Reachability.\n * @param {object} webex\n * @memberof Reachability\n */\n constructor(webex: object) {\n super();\n this.webex = webex;\n\n /**\n * internal request object for the server\n * @instance\n * @type {Array}\n * @private\n * @memberof Reachability\n */\n this.reachabilityRequest = new ReachabilityRequest(this.webex);\n\n this.clusterReachability = {};\n }\n\n /**\n * Gets a list of media clusters from the backend and performs reachability checks on all the clusters\n * @returns {Promise<ReachabilityResults>} reachability results\n * @public\n * @memberof Reachability\n */\n public async gatherReachability(): Promise<ReachabilityResults> {\n // Fetch clusters and measure latency\n try {\n const {clusters, joinCookie} = await this.reachabilityRequest.getClusters(\n MeetingUtil.getIpVersion(this.webex)\n );\n\n // @ts-ignore\n await this.webex.boundedStorage.put(\n this.namespace,\n REACHABILITY.localStorageJoinCookie,\n JSON.stringify(joinCookie)\n );\n\n this.reachabilityDefer = new Defer();\n\n // Perform Reachability Check\n await this.performReachabilityChecks(clusters);\n\n return this.reachabilityDefer.promise;\n } catch (error) {\n LoggerProxy.logger.error(`Reachability:index#gatherReachability --> Error:`, error);\n\n return {};\n }\n }\n\n /**\n * Returns statistics about last reachability results. The returned value is an object\n * with a flat list of properties so that it can be easily sent with metrics\n *\n * @returns {Promise} Promise with metrics values, it never rejects/throws.\n */\n async getReachabilityMetrics(): Promise<ReachabilityMetrics> {\n const stats: ReachabilityMetrics = {\n reachability_public_udp_success: 0,\n reachability_public_udp_failed: 0,\n reachability_public_tcp_success: 0,\n reachability_public_tcp_failed: 0,\n reachability_public_xtls_success: 0,\n reachability_public_xtls_failed: 0,\n reachability_vmn_udp_success: 0,\n reachability_vmn_udp_failed: 0,\n reachability_vmn_tcp_success: 0,\n reachability_vmn_tcp_failed: 0,\n reachability_vmn_xtls_success: 0,\n reachability_vmn_xtls_failed: 0,\n };\n\n const updateStats = (clusterType: 'public' | 'vmn', result: ClusterReachabilityResult) => {\n if (result.udp && result.udp.result !== 'untested') {\n const outcome = result.udp.result === 'reachable' ? 'success' : 'failed';\n stats[`reachability_${clusterType}_udp_${outcome}`] += 1;\n }\n if (result.tcp && result.tcp.result !== 'untested') {\n const outcome = result.tcp.result === 'reachable' ? 'success' : 'failed';\n stats[`reachability_${clusterType}_tcp_${outcome}`] += 1;\n }\n if (result.xtls && result.xtls.result !== 'untested') {\n const outcome = result.xtls.result === 'reachable' ? 'success' : 'failed';\n stats[`reachability_${clusterType}_xtls_${outcome}`] += 1;\n }\n };\n\n try {\n // @ts-ignore\n const resultsJson = await this.webex.boundedStorage.get(\n REACHABILITY.namespace,\n REACHABILITY.localStorageResult\n );\n\n const results: ReachabilityResults = JSON.parse(resultsJson);\n\n Object.values(results).forEach((result) => {\n updateStats(result.isVideoMesh ? 'vmn' : 'public', result);\n });\n } catch (e) {\n // empty storage, that's ok\n LoggerProxy.logger.warn(\n 'Roap:request#getReachabilityMetrics --> Error parsing reachability data: ',\n e\n );\n }\n\n return stats;\n }\n\n /**\n * Maps our internal transport result to the format that backend expects\n * @param {TransportResult} transportResult\n * @returns {TransportResultForBackend}\n */\n private mapTransportResultToBackendDataFormat(\n transportResult: TransportResult\n ): TransportResultForBackend {\n const output: TransportResultForBackend = {};\n\n for (const [key, value] of Object.entries(transportResult)) {\n switch (key) {\n case 'result':\n switch (value) {\n case 'reachable':\n output.reachable = 'true';\n break;\n case 'unreachable':\n output.reachable = 'false';\n break;\n case 'untested':\n output.untested = 'true';\n break;\n }\n break;\n case 'latencyInMilliseconds':\n output.latencyInMilliseconds = value.toString();\n break;\n default:\n output[key] = value;\n }\n }\n\n return output;\n }\n\n /**\n * Reachability results as an object in the format that backend expects\n *\n * @returns {any} reachability results that need to be sent to the backend\n */\n async getReachabilityResults(): Promise<ReachabilityResultsForBackend | undefined> {\n let results: ReachabilityResultsForBackend;\n\n try {\n // @ts-ignore\n const resultsJson = await this.webex.boundedStorage.get(\n REACHABILITY.namespace,\n REACHABILITY.localStorageResult\n );\n\n const allClusterResults: ReachabilityResults = JSON.parse(resultsJson);\n\n results = mapValues(allClusterResults, (clusterResult) => ({\n udp: this.mapTransportResultToBackendDataFormat(clusterResult.udp || {result: 'untested'}),\n tcp: this.mapTransportResultToBackendDataFormat(clusterResult.tcp || {result: 'untested'}),\n xtls: this.mapTransportResultToBackendDataFormat(\n clusterResult.xtls || {result: 'untested'}\n ),\n }));\n } catch (e) {\n // empty storage, that's ok\n LoggerProxy.logger.warn(\n 'Roap:request#attachReachabilityData --> Error parsing reachability data: ',\n e\n );\n }\n\n return results;\n }\n\n /**\n * fetches reachability data and checks for cluster reachability\n * @returns {boolean}\n * @public\n * @memberof Reachability\n */\n async isAnyPublicClusterReachable() {\n let reachable = false;\n // @ts-ignore\n const reachabilityData = await this.webex.boundedStorage\n .get(this.namespace, REACHABILITY.localStorageResult)\n .catch(() => {});\n\n if (reachabilityData) {\n try {\n const reachabilityResults: ReachabilityResults = JSON.parse(reachabilityData);\n\n reachable = Object.values(reachabilityResults).some(\n (result) =>\n !result.isVideoMesh &&\n (result.udp?.result === 'reachable' || result.tcp?.result === 'reachable')\n );\n } catch (e) {\n LoggerProxy.logger.error(\n `Roap:request#attachReachabilityData --> Error in parsing reachability data: ${e}`\n );\n }\n }\n\n return reachable;\n }\n\n /**\n * Returns true only if ALL protocols (UDP, TCP and TLS) have been tested and none\n * of the media clusters where reachable with any of the protocols. This is done\n * irrespective of the config, so for example:\n * if config.meetings.experimental.enableTlsReachability === false,\n * it will return false, because TLS reachability won't be tested,\n * so we can't say for sure that media backend is unreachable over TLS.\n *\n * @returns {boolean}\n */\n async isWebexMediaBackendUnreachable() {\n let unreachable = false;\n\n // @ts-ignore\n const reachabilityData = await this.webex.boundedStorage\n .get(this.namespace, REACHABILITY.localStorageResult)\n .catch(() => {});\n\n if (reachabilityData) {\n try {\n const reachabilityResults: ReachabilityResults = JSON.parse(reachabilityData);\n\n const protocols = {\n udp: {tested: false, reachable: undefined},\n tcp: {tested: false, reachable: undefined},\n xtls: {tested: false, reachable: undefined},\n };\n\n Object.values(reachabilityResults).forEach((result) => {\n Object.keys(protocols).forEach((protocol) => {\n if (\n result[protocol]?.result === 'reachable' ||\n result[protocol]?.result === 'unreachable'\n ) {\n protocols[protocol].tested = true;\n\n // we need at least 1 'reachable' result to mark the whole protocol as reachable\n if (result[protocol].result === 'reachable') {\n protocols[protocol].reachable = true;\n }\n }\n });\n });\n\n unreachable = Object.values(protocols).every(\n (protocol) => protocol.tested && !protocol.reachable\n );\n } catch (e) {\n LoggerProxy.logger.error(\n `Roap:request#attachReachabilityData --> Error in parsing reachability data: ${e}`\n );\n }\n }\n\n return unreachable;\n }\n\n /**\n * Get list of all unreachable clusters\n * @returns {array} Unreachable clusters\n * @private\n * @memberof Reachability\n */\n private getUnreachableClusters(): Array<{name: string; protocol: string}> {\n const unreachableList = [];\n\n Object.entries(this.clusterReachability).forEach(([key, clusterReachability]) => {\n const result = clusterReachability.getResult();\n\n if (result.udp.result === 'unreachable') {\n unreachableList.push({name: key, protocol: 'udp'});\n }\n if (result.tcp.result === 'unreachable') {\n unreachableList.push({name: key, protocol: 'tcp'});\n }\n if (result.xtls.result === 'unreachable') {\n unreachableList.push({name: key, protocol: 'xtls'});\n }\n });\n\n return unreachableList;\n }\n\n /**\n * Make a log of unreachable clusters.\n * @returns {undefined}\n * @private\n * @memberof Reachability\n */\n private logUnreachableClusters() {\n const list = this.getUnreachableClusters();\n\n list.forEach(({name, protocol}) => {\n LoggerProxy.logger.log(\n `Reachability:index#logUnreachableClusters --> failed to reach ${name} over ${protocol}`\n );\n });\n }\n\n /**\n * Returns true if we've obtained all the reachability results for all the public clusters\n * In other words, it means that all public clusters are reachable over each protocol,\n * because we only get a \"result\" if we managed to reach a cluster\n *\n * @returns {boolean}\n */\n private areAllPublicClusterResultsReady() {\n return isEqual(this.expectedResultsCount.public, this.resultsCount.public);\n }\n\n /**\n * Returns true if we've obtained all the reachability results for all the clusters\n *\n * @returns {boolean}\n */\n private areAllResultsReady() {\n return isEqual(this.expectedResultsCount, this.resultsCount);\n }\n\n /**\n * Resolves the promise returned by gatherReachability() method\n * @returns {void}\n */\n private resolveReachabilityPromise() {\n if (this.vmnTimer) {\n clearTimeout(this.vmnTimer);\n }\n if (this.publicCloudTimer) {\n clearTimeout(this.publicCloudTimer);\n }\n\n this.logUnreachableClusters();\n this.reachabilityDefer?.resolve();\n }\n\n /**\n * Aborts all cluster reachability checks that are in progress\n *\n * @returns {void}\n */\n private abortClusterReachability() {\n Object.values(this.clusterReachability).forEach((clusterReachability) => {\n clusterReachability.abort();\n });\n }\n\n /**\n * Helper function for calculating min/max/average values of latency\n *\n * @param {Array<any>} results\n * @param {string} protocol\n * @param {boolean} isVideoMesh\n * @returns {{min:number, max: number, average: number}}\n */\n protected getStatistics(\n results: Array<ClusterReachabilityResult & {isVideoMesh: boolean}>,\n protocol: 'udp' | 'tcp' | 'xtls',\n isVideoMesh: boolean\n ) {\n const values = results\n .filter((result) => result.isVideoMesh === isVideoMesh)\n .filter((result) => result[protocol].result === 'reachable')\n .map((result) => result[protocol].latencyInMilliseconds);\n\n if (values.length === 0) {\n return {\n min: -1,\n max: -1,\n average: -1,\n };\n }\n\n return {\n min: Math.min(...values),\n max: Math.max(...values),\n average: mean(values),\n };\n }\n\n /**\n * Sends a metric with all the statistics about how long reachability took\n *\n * @returns {void}\n */\n protected async sendMetric() {\n const results = [];\n\n Object.values(this.clusterReachability).forEach((clusterReachability) => {\n results.push({\n ...clusterReachability.getResult(),\n isVideoMesh: clusterReachability.isVideoMesh,\n });\n });\n\n const stats = {\n vmn: {\n udp: this.getStatistics(results, 'udp', true),\n },\n public: {\n udp: this.getStatistics(results, 'udp', false),\n tcp: this.getStatistics(results, 'tcp', false),\n xtls: this.getStatistics(results, 'xtls', false),\n },\n };\n Metrics.sendBehavioralMetric(\n BEHAVIORAL_METRICS.REACHABILITY_COMPLETED,\n Metrics.prepareMetricFields(stats)\n );\n }\n\n /**\n * Starts all the timers used for various timeouts\n *\n * @returns {void}\n */\n private startTimers() {\n this.vmnTimer = setTimeout(() => {\n this.vmnTimer = undefined;\n // if we are only missing VMN results, then we don't want to wait for them any longer\n // as they are likely to fail if users are not on corporate network\n if (this.areAllPublicClusterResultsReady()) {\n LoggerProxy.logger.log(\n 'Reachability:index#startTimers --> Reachability checks timed out (VMN timeout)'\n );\n\n this.resolveReachabilityPromise();\n }\n }, VIDEO_MESH_TIMEOUT * 1000);\n\n this.publicCloudTimer = setTimeout(() => {\n this.publicCloudTimer = undefined;\n\n LoggerProxy.logger.log(\n `Reachability:index#startTimers --> Reachability checks timed out (${DEFAULT_TIMEOUT}s)`\n );\n\n // resolve the promise, so that the client won't be blocked waiting on meetings.register() for too long\n this.resolveReachabilityPromise();\n }, DEFAULT_TIMEOUT * 1000);\n\n this.overallTimer = setTimeout(() => {\n this.overallTimer = undefined;\n this.abortClusterReachability();\n this.emit(\n {\n file: 'reachability',\n function: 'overallTimer timeout',\n },\n 'reachability:done',\n {}\n );\n this.sendMetric();\n\n LoggerProxy.logger.log(\n `Reachability:index#startTimers --> Reachability checks fully timed out (${OVERALL_TIMEOUT}s)`\n );\n }, OVERALL_TIMEOUT * 1000);\n }\n\n /**\n * Stores given reachability results in local storage\n *\n * @param {ReachabilityResults} results\n * @returns {Promise<void>}\n */\n private async storeResults(results: ReachabilityResults) {\n // @ts-ignore\n await this.webex.boundedStorage.put(\n this.namespace,\n REACHABILITY.localStorageResult,\n JSON.stringify(results)\n );\n }\n\n /**\n * Resets all the internal counters that keep track of the results\n *\n * @returns {void}\n */\n private resetResultCounters() {\n this.expectedResultsCount.videoMesh.udp = 0;\n this.expectedResultsCount.public.udp = 0;\n this.expectedResultsCount.public.tcp = 0;\n this.expectedResultsCount.public.xtls = 0;\n\n this.resultsCount.videoMesh.udp = 0;\n this.resultsCount.public.udp = 0;\n this.resultsCount.public.tcp = 0;\n this.resultsCount.public.xtls = 0;\n }\n\n /**\n * Performs reachability checks for all clusters\n * @param {ClusterList} clusterList\n * @returns {Promise<void>} promise that's resolved as soon as the checks are started\n */\n private async performReachabilityChecks(clusterList: ClusterList) {\n const results: ReachabilityResults = {};\n\n this.clusterReachability = {};\n\n if (!clusterList || !Object.keys(clusterList).length) {\n return;\n }\n\n LoggerProxy.logger.log(\n `Reachability:index#performReachabilityChecks --> doing UDP${\n // @ts-ignore\n this.webex.config.meetings.experimental.enableTcpReachability ? ',TCP' : ''\n }${\n // @ts-ignore\n this.webex.config.meetings.experimental.enableTlsReachability ? ',TLS' : ''\n } reachability checks`\n );\n\n this.resetResultCounters();\n this.startTimers();\n\n // sanitize the urls in the clusterList\n Object.keys(clusterList).forEach((key) => {\n const cluster = clusterList[key];\n\n // Linus doesn't support TCP reachability checks on video mesh nodes\n const includeTcpReachability =\n // @ts-ignore\n this.webex.config.meetings.experimental.enableTcpReachability && !cluster.isVideoMesh;\n\n if (!includeTcpReachability) {\n cluster.tcp = [];\n }\n\n // Linus doesn't support xTLS reachability checks on video mesh nodes\n const includeTlsReachability =\n // @ts-ignore\n this.webex.config.meetings.experimental.enableTlsReachability && !cluster.isVideoMesh;\n\n if (!includeTlsReachability) {\n cluster.xtls = [];\n }\n\n // initialize the result for this cluster\n results[key] = {\n udp: {result: cluster.udp.length > 0 ? 'unreachable' : 'untested'},\n tcp: {result: cluster.tcp.length > 0 ? 'unreachable' : 'untested'},\n xtls: {result: cluster.xtls.length > 0 ? 'unreachable' : 'untested'},\n isVideoMesh: cluster.isVideoMesh,\n };\n\n // update expected results counters to include this cluster\n this.expectedResultsCount[cluster.isVideoMesh ? 'videoMesh' : 'public'].udp +=\n cluster.udp.length;\n if (!cluster.isVideoMesh) {\n this.expectedResultsCount.public.tcp += cluster.tcp.length;\n this.expectedResultsCount.public.xtls += cluster.xtls.length;\n }\n });\n\n const isFirstResult = {\n udp: true,\n tcp: true,\n xtls: true,\n };\n\n // save the initialized results (in case we don't get any \"resultReady\" events at all)\n await this.storeResults(results);\n\n // now start the reachability on all the clusters\n Object.keys(clusterList).forEach((key) => {\n const cluster = clusterList[key];\n\n this.clusterReachability[key] = new ClusterReachability(key, cluster);\n this.clusterReachability[key].on(Events.resultReady, async (data: ResultEventData) => {\n const {protocol, result, clientMediaIPs, latencyInMilliseconds} = data;\n\n if (isFirstResult[protocol]) {\n this.emit(\n {\n file: 'reachability',\n function: 'resultReady event handler',\n },\n 'reachability:firstResultAvailable',\n {\n protocol,\n }\n );\n isFirstResult[protocol] = false;\n }\n this.resultsCount[cluster.isVideoMesh ? 'videoMesh' : 'public'][protocol] += 1;\n\n const areAllResultsReady = this.areAllResultsReady();\n\n results[key][protocol].result = result;\n results[key][protocol].clientMediaIPs = clientMediaIPs;\n results[key][protocol].latencyInMilliseconds = latencyInMilliseconds;\n\n await this.storeResults(results);\n\n if (areAllResultsReady) {\n clearTimeout(this.overallTimer);\n this.overallTimer = undefined;\n this.emit(\n {\n file: 'reachability',\n function: 'performReachabilityChecks',\n },\n 'reachability:done',\n {}\n );\n this.sendMetric();\n\n LoggerProxy.logger.log(\n `Reachability:index#gatherReachability --> Reachability checks fully completed`\n );\n this.resolveReachabilityPromise();\n }\n });\n\n // clientMediaIps can be updated independently from the results, so we need to listen for them too\n this.clusterReachability[key].on(\n Events.clientMediaIpsUpdated,\n async (data: ClientMediaIpsUpdatedEventData) => {\n results[key][data.protocol].clientMediaIPs = data.clientMediaIPs;\n\n await this.storeResults(results);\n }\n );\n\n this.clusterReachability[key].start(); // not awaiting on purpose\n });\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["_lodash","require","_common","_loggerProxy","_interopRequireDefault","_util","_constants","_request","_clusterReachability","_eventsScope","_constants2","_metrics","ownKeys","e","r","t","_Object$keys2","_Object$getOwnPropertySymbols","o","filter","_Object$getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","arguments","length","Object","forEach","_defineProperty2","default","_Object$getOwnPropertyDescriptors","_Object$defineProperties","_Object$defineProperty","_createSuper","Derived","hasNativeReflectConstruct","_isNativeReflectConstruct","_createSuperInternal","Super","_getPrototypeOf2","result","NewTarget","constructor","_Reflect$construct","_possibleConstructorReturn2","Reflect","sham","Proxy","Boolean","prototype","valueOf","call","DEFAULT_TIMEOUT","VIDEO_MESH_TIMEOUT","OVERALL_TIMEOUT","Reachability","exports","_EventsScope","_inherits2","_super","webex","_this","_classCallCheck2","_assertThisInitialized2","REACHABILITY","namespace","videoMesh","udp","public","tcp","xtls","reachabilityRequest","ReachabilityRequest","clusterReachability","_createClass2","key","value","_getClusters","_asyncToGenerator2","_regenerator","mark","_callee","isRetry","_yield$this$reachabil","clusters","joinCookie","_args","wrap","_callee$","_context","prev","next","undefined","getClusters","MeetingUtil","getIpVersion","sent","abrupt","t0","LoggerProxy","logger","error","concat","stop","_gatherReachability","_callee2","_yield$this$getCluste","_callee2$","_context2","boundedStorage","put","localStorageJoinCookie","_stringify","reachabilityDefer","Defer","performReachabilityChecks","promise","gatherReachability","_getReachabilityMetrics","_callee3","stats","updateStats","resultsJson","results","_callee3$","_context3","reachability_public_udp_success","reachability_public_udp_failed","reachability_public_tcp_success","reachability_public_tcp_failed","reachability_public_xtls_success","reachability_public_xtls_failed","reachability_vmn_udp_success","reachability_vmn_udp_failed","reachability_vmn_tcp_success","reachability_vmn_tcp_failed","reachability_vmn_xtls_success","reachability_vmn_xtls_failed","clusterType","outcome","get","localStorageResult","JSON","parse","_values","isVideoMesh","warn","getReachabilityMetrics","mapTransportResultToBackendDataFormat","transportResult","output","_i","_Object$entries","_entries","_Object$entries$_i","_slicedToArray2","reachable","untested","latencyInMilliseconds","toString","_getReachabilityResults","_callee4","_this2","allClusterResults","_callee4$","_context4","mapValues","clusterResult","getReachabilityResults","_isAnyPublicClusterReachable","_callee5","reachabilityData","reachabilityResults","_callee5$","_context5","catch","some","_result$udp","_result$tcp","isAnyPublicClusterReachable","_isWebexMediaBackendUnreachable","_callee6","unreachable","protocols","_callee6$","_context6","tested","_keys","protocol","_result$protocol","_result$protocol2","every","isWebexMediaBackendUnreachable","getUnreachableClusters","unreachableList","_ref","_ref2","getResult","name","logUnreachableClusters","list","_ref3","log","areAllPublicClusterResultsReady","isEqual","expectedResultsCount","resultsCount","areAllResultsReady","resolveReachabilityPromise","_this$reachabilityDef","vmnTimer","clearTimeout","publicCloudTimer","resolve","abortClusterReachability","abort","getStatistics","values","map","min","max","average","Math","_toConsumableArray2","mean","_sendMetric","_callee7","_callee7$","_context7","vmn","Metrics","sendBehavioralMetric","BEHAVIORAL_METRICS","REACHABILITY_COMPLETED","prepareMetricFields","sendMetric","startTimers","_this3","setTimeout","overallTimer","emit","file","function","_storeResults","_callee8","_callee8$","_context8","storeResults","_x","resetResultCounters","_performReachabilityChecks","_callee11","clusterList","_this4","isFirstResult","_callee11$","_context11","config","meetings","experimental","enableTcpReachability","enableTlsReachability","cluster","includeTcpReachability","includeTlsReachability","ClusterReachability","on","Events","resultReady","_ref4","_callee9","data","clientMediaIPs","_callee9$","_context9","_x3","clientMediaIpsUpdated","_ref5","_callee10","_callee10$","_context10","_x4","start","_x2","EventsScope"],"sources":["index.ts"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\n/* eslint-disable class-methods-use-this */\nimport {isEqual, mapValues, mean} from 'lodash';\n\nimport {Defer} from '@webex/common';\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport MeetingUtil from '../meeting/util';\n\nimport {REACHABILITY} from '../constants';\n\nimport ReachabilityRequest, {ClusterList} from './request';\nimport {\n ClientMediaIpsUpdatedEventData,\n ClusterReachability,\n ClusterReachabilityResult,\n Events,\n ResultEventData,\n TransportResult,\n} from './clusterReachability';\nimport EventsScope from '../common/events/events-scope';\nimport BEHAVIORAL_METRICS from '../metrics/constants';\nimport Metrics from '../metrics';\n\nexport type ReachabilityMetrics = {\n reachability_public_udp_success: number;\n reachability_public_udp_failed: number;\n reachability_public_tcp_success: number;\n reachability_public_tcp_failed: number;\n reachability_public_xtls_success: number;\n reachability_public_xtls_failed: number;\n reachability_vmn_udp_success: number;\n reachability_vmn_udp_failed: number;\n reachability_vmn_tcp_success: number;\n reachability_vmn_tcp_failed: number;\n reachability_vmn_xtls_success: number;\n reachability_vmn_xtls_failed: number;\n};\n\n/**\n * This is the type that matches what backend expects us to send to them. It is a bit weird, because\n * it uses strings instead of booleans and numbers, but that's what they require.\n */\nexport type TransportResultForBackend = {\n reachable?: 'true' | 'false';\n latencyInMilliseconds?: string;\n clientMediaIPs?: string[];\n untested?: 'true';\n};\n\nexport type ReachabilityResultForBackend = {\n udp: TransportResultForBackend;\n tcp: TransportResultForBackend;\n xtls: TransportResultForBackend;\n};\n\n// this is the type that is required by the backend when we send them reachability results\nexport type ReachabilityResultsForBackend = Record<string, ReachabilityResultForBackend>;\n\n// this is the type used by Reachability class internally and stored in local storage\nexport type ReachabilityResults = Record<\n string,\n ClusterReachabilityResult & {\n isVideoMesh?: boolean;\n }\n>;\n\n// timeouts in seconds\nconst DEFAULT_TIMEOUT = 3;\nconst VIDEO_MESH_TIMEOUT = 1;\nconst OVERALL_TIMEOUT = 15;\n\n/**\n * @class Reachability\n * @export\n */\nexport default class Reachability extends EventsScope {\n namespace = REACHABILITY.namespace;\n webex: object;\n reachabilityRequest: ReachabilityRequest;\n clusterReachability: {\n [key: string]: ClusterReachability;\n };\n\n reachabilityDefer?: Defer;\n\n vmnTimer?: ReturnType<typeof setTimeout>;\n publicCloudTimer?: ReturnType<typeof setTimeout>;\n overallTimer?: ReturnType<typeof setTimeout>;\n\n expectedResultsCount = {videoMesh: {udp: 0}, public: {udp: 0, tcp: 0, xtls: 0}};\n resultsCount = {videoMesh: {udp: 0}, public: {udp: 0, tcp: 0, xtls: 0}};\n\n /**\n * Creates an instance of Reachability.\n * @param {object} webex\n * @memberof Reachability\n */\n constructor(webex: object) {\n super();\n this.webex = webex;\n\n /**\n * internal request object for the server\n * @instance\n * @type {Array}\n * @private\n * @memberof Reachability\n */\n this.reachabilityRequest = new ReachabilityRequest(this.webex);\n\n this.clusterReachability = {};\n }\n\n /**\n * Fetches the list of media clusters from the backend\n * @param {boolean} isRetry\n * @private\n * @returns {Promise<{clusters: ClusterList, joinCookie: any}>}\n */\n async getClusters(isRetry = false): Promise<{clusters: ClusterList; joinCookie: any}> {\n try {\n const {clusters, joinCookie} = await this.reachabilityRequest.getClusters(\n MeetingUtil.getIpVersion(this.webex)\n );\n\n return {clusters, joinCookie};\n } catch (error) {\n if (isRetry) {\n throw error;\n }\n\n LoggerProxy.logger.error(\n `Reachability:index#getClusters --> Failed with error: ${error}, retrying...`\n );\n\n return this.getClusters(true);\n }\n }\n\n /**\n * Gets a list of media clusters from the backend and performs reachability checks on all the clusters\n * @returns {Promise<ReachabilityResults>} reachability results\n * @public\n * @memberof Reachability\n */\n public async gatherReachability(): Promise<ReachabilityResults> {\n // Fetch clusters and measure latency\n try {\n const {clusters, joinCookie} = await this.getClusters();\n\n // @ts-ignore\n await this.webex.boundedStorage.put(\n this.namespace,\n REACHABILITY.localStorageJoinCookie,\n JSON.stringify(joinCookie)\n );\n\n this.reachabilityDefer = new Defer();\n\n // Perform Reachability Check\n await this.performReachabilityChecks(clusters);\n\n return this.reachabilityDefer.promise;\n } catch (error) {\n LoggerProxy.logger.error(`Reachability:index#gatherReachability --> Error:`, error);\n\n return {};\n }\n }\n\n /**\n * Returns statistics about last reachability results. The returned value is an object\n * with a flat list of properties so that it can be easily sent with metrics\n *\n * @returns {Promise} Promise with metrics values, it never rejects/throws.\n */\n async getReachabilityMetrics(): Promise<ReachabilityMetrics> {\n const stats: ReachabilityMetrics = {\n reachability_public_udp_success: 0,\n reachability_public_udp_failed: 0,\n reachability_public_tcp_success: 0,\n reachability_public_tcp_failed: 0,\n reachability_public_xtls_success: 0,\n reachability_public_xtls_failed: 0,\n reachability_vmn_udp_success: 0,\n reachability_vmn_udp_failed: 0,\n reachability_vmn_tcp_success: 0,\n reachability_vmn_tcp_failed: 0,\n reachability_vmn_xtls_success: 0,\n reachability_vmn_xtls_failed: 0,\n };\n\n const updateStats = (clusterType: 'public' | 'vmn', result: ClusterReachabilityResult) => {\n if (result.udp && result.udp.result !== 'untested') {\n const outcome = result.udp.result === 'reachable' ? 'success' : 'failed';\n stats[`reachability_${clusterType}_udp_${outcome}`] += 1;\n }\n if (result.tcp && result.tcp.result !== 'untested') {\n const outcome = result.tcp.result === 'reachable' ? 'success' : 'failed';\n stats[`reachability_${clusterType}_tcp_${outcome}`] += 1;\n }\n if (result.xtls && result.xtls.result !== 'untested') {\n const outcome = result.xtls.result === 'reachable' ? 'success' : 'failed';\n stats[`reachability_${clusterType}_xtls_${outcome}`] += 1;\n }\n };\n\n try {\n // @ts-ignore\n const resultsJson = await this.webex.boundedStorage.get(\n REACHABILITY.namespace,\n REACHABILITY.localStorageResult\n );\n\n const results: ReachabilityResults = JSON.parse(resultsJson);\n\n Object.values(results).forEach((result) => {\n updateStats(result.isVideoMesh ? 'vmn' : 'public', result);\n });\n } catch (e) {\n // empty storage, that's ok\n LoggerProxy.logger.warn(\n 'Roap:request#getReachabilityMetrics --> Error parsing reachability data: ',\n e\n );\n }\n\n return stats;\n }\n\n /**\n * Maps our internal transport result to the format that backend expects\n * @param {TransportResult} transportResult\n * @returns {TransportResultForBackend}\n */\n private mapTransportResultToBackendDataFormat(\n transportResult: TransportResult\n ): TransportResultForBackend {\n const output: TransportResultForBackend = {};\n\n for (const [key, value] of Object.entries(transportResult)) {\n switch (key) {\n case 'result':\n switch (value) {\n case 'reachable':\n output.reachable = 'true';\n break;\n case 'unreachable':\n output.reachable = 'false';\n break;\n case 'untested':\n output.untested = 'true';\n break;\n }\n break;\n case 'latencyInMilliseconds':\n output.latencyInMilliseconds = value.toString();\n break;\n default:\n output[key] = value;\n }\n }\n\n return output;\n }\n\n /**\n * Reachability results as an object in the format that backend expects\n *\n * @returns {any} reachability results that need to be sent to the backend\n */\n async getReachabilityResults(): Promise<ReachabilityResultsForBackend | undefined> {\n let results: ReachabilityResultsForBackend;\n\n try {\n // @ts-ignore\n const resultsJson = await this.webex.boundedStorage.get(\n REACHABILITY.namespace,\n REACHABILITY.localStorageResult\n );\n\n const allClusterResults: ReachabilityResults = JSON.parse(resultsJson);\n\n results = mapValues(allClusterResults, (clusterResult) => ({\n udp: this.mapTransportResultToBackendDataFormat(clusterResult.udp || {result: 'untested'}),\n tcp: this.mapTransportResultToBackendDataFormat(clusterResult.tcp || {result: 'untested'}),\n xtls: this.mapTransportResultToBackendDataFormat(\n clusterResult.xtls || {result: 'untested'}\n ),\n }));\n } catch (e) {\n // empty storage, that's ok\n LoggerProxy.logger.warn(\n 'Roap:request#attachReachabilityData --> Error parsing reachability data: ',\n e\n );\n }\n\n return results;\n }\n\n /**\n * fetches reachability data and checks for cluster reachability\n * @returns {boolean}\n * @public\n * @memberof Reachability\n */\n async isAnyPublicClusterReachable() {\n let reachable = false;\n // @ts-ignore\n const reachabilityData = await this.webex.boundedStorage\n .get(this.namespace, REACHABILITY.localStorageResult)\n .catch(() => {});\n\n if (reachabilityData) {\n try {\n const reachabilityResults: ReachabilityResults = JSON.parse(reachabilityData);\n\n reachable = Object.values(reachabilityResults).some(\n (result) =>\n !result.isVideoMesh &&\n (result.udp?.result === 'reachable' || result.tcp?.result === 'reachable')\n );\n } catch (e) {\n LoggerProxy.logger.error(\n `Roap:request#attachReachabilityData --> Error in parsing reachability data: ${e}`\n );\n }\n }\n\n return reachable;\n }\n\n /**\n * Returns true only if ALL protocols (UDP, TCP and TLS) have been tested and none\n * of the media clusters where reachable with any of the protocols. This is done\n * irrespective of the config, so for example:\n * if config.meetings.experimental.enableTlsReachability === false,\n * it will return false, because TLS reachability won't be tested,\n * so we can't say for sure that media backend is unreachable over TLS.\n *\n * @returns {boolean}\n */\n async isWebexMediaBackendUnreachable() {\n let unreachable = false;\n\n // @ts-ignore\n const reachabilityData = await this.webex.boundedStorage\n .get(this.namespace, REACHABILITY.localStorageResult)\n .catch(() => {});\n\n if (reachabilityData) {\n try {\n const reachabilityResults: ReachabilityResults = JSON.parse(reachabilityData);\n\n const protocols = {\n udp: {tested: false, reachable: undefined},\n tcp: {tested: false, reachable: undefined},\n xtls: {tested: false, reachable: undefined},\n };\n\n Object.values(reachabilityResults).forEach((result) => {\n Object.keys(protocols).forEach((protocol) => {\n if (\n result[protocol]?.result === 'reachable' ||\n result[protocol]?.result === 'unreachable'\n ) {\n protocols[protocol].tested = true;\n\n // we need at least 1 'reachable' result to mark the whole protocol as reachable\n if (result[protocol].result === 'reachable') {\n protocols[protocol].reachable = true;\n }\n }\n });\n });\n\n unreachable = Object.values(protocols).every(\n (protocol) => protocol.tested && !protocol.reachable\n );\n } catch (e) {\n LoggerProxy.logger.error(\n `Roap:request#attachReachabilityData --> Error in parsing reachability data: ${e}`\n );\n }\n }\n\n return unreachable;\n }\n\n /**\n * Get list of all unreachable clusters\n * @returns {array} Unreachable clusters\n * @private\n * @memberof Reachability\n */\n private getUnreachableClusters(): Array<{name: string; protocol: string}> {\n const unreachableList = [];\n\n Object.entries(this.clusterReachability).forEach(([key, clusterReachability]) => {\n const result = clusterReachability.getResult();\n\n if (result.udp.result === 'unreachable') {\n unreachableList.push({name: key, protocol: 'udp'});\n }\n if (result.tcp.result === 'unreachable') {\n unreachableList.push({name: key, protocol: 'tcp'});\n }\n if (result.xtls.result === 'unreachable') {\n unreachableList.push({name: key, protocol: 'xtls'});\n }\n });\n\n return unreachableList;\n }\n\n /**\n * Make a log of unreachable clusters.\n * @returns {undefined}\n * @private\n * @memberof Reachability\n */\n private logUnreachableClusters() {\n const list = this.getUnreachableClusters();\n\n list.forEach(({name, protocol}) => {\n LoggerProxy.logger.log(\n `Reachability:index#logUnreachableClusters --> failed to reach ${name} over ${protocol}`\n );\n });\n }\n\n /**\n * Returns true if we've obtained all the reachability results for all the public clusters\n * In other words, it means that all public clusters are reachable over each protocol,\n * because we only get a \"result\" if we managed to reach a cluster\n *\n * @returns {boolean}\n */\n private areAllPublicClusterResultsReady() {\n return isEqual(this.expectedResultsCount.public, this.resultsCount.public);\n }\n\n /**\n * Returns true if we've obtained all the reachability results for all the clusters\n *\n * @returns {boolean}\n */\n private areAllResultsReady() {\n return isEqual(this.expectedResultsCount, this.resultsCount);\n }\n\n /**\n * Resolves the promise returned by gatherReachability() method\n * @returns {void}\n */\n private resolveReachabilityPromise() {\n if (this.vmnTimer) {\n clearTimeout(this.vmnTimer);\n }\n if (this.publicCloudTimer) {\n clearTimeout(this.publicCloudTimer);\n }\n\n this.logUnreachableClusters();\n this.reachabilityDefer?.resolve();\n }\n\n /**\n * Aborts all cluster reachability checks that are in progress\n *\n * @returns {void}\n */\n private abortClusterReachability() {\n Object.values(this.clusterReachability).forEach((clusterReachability) => {\n clusterReachability.abort();\n });\n }\n\n /**\n * Helper function for calculating min/max/average values of latency\n *\n * @param {Array<any>} results\n * @param {string} protocol\n * @param {boolean} isVideoMesh\n * @returns {{min:number, max: number, average: number}}\n */\n protected getStatistics(\n results: Array<ClusterReachabilityResult & {isVideoMesh: boolean}>,\n protocol: 'udp' | 'tcp' | 'xtls',\n isVideoMesh: boolean\n ) {\n const values = results\n .filter((result) => result.isVideoMesh === isVideoMesh)\n .filter((result) => result[protocol].result === 'reachable')\n .map((result) => result[protocol].latencyInMilliseconds);\n\n if (values.length === 0) {\n return {\n min: -1,\n max: -1,\n average: -1,\n };\n }\n\n return {\n min: Math.min(...values),\n max: Math.max(...values),\n average: mean(values),\n };\n }\n\n /**\n * Sends a metric with all the statistics about how long reachability took\n *\n * @returns {void}\n */\n protected async sendMetric() {\n const results = [];\n\n Object.values(this.clusterReachability).forEach((clusterReachability) => {\n results.push({\n ...clusterReachability.getResult(),\n isVideoMesh: clusterReachability.isVideoMesh,\n });\n });\n\n const stats = {\n vmn: {\n udp: this.getStatistics(results, 'udp', true),\n },\n public: {\n udp: this.getStatistics(results, 'udp', false),\n tcp: this.getStatistics(results, 'tcp', false),\n xtls: this.getStatistics(results, 'xtls', false),\n },\n };\n Metrics.sendBehavioralMetric(\n BEHAVIORAL_METRICS.REACHABILITY_COMPLETED,\n Metrics.prepareMetricFields(stats)\n );\n }\n\n /**\n * Starts all the timers used for various timeouts\n *\n * @returns {void}\n */\n private startTimers() {\n this.vmnTimer = setTimeout(() => {\n this.vmnTimer = undefined;\n // if we are only missing VMN results, then we don't want to wait for them any longer\n // as they are likely to fail if users are not on corporate network\n if (this.areAllPublicClusterResultsReady()) {\n LoggerProxy.logger.log(\n 'Reachability:index#startTimers --> Reachability checks timed out (VMN timeout)'\n );\n\n this.resolveReachabilityPromise();\n }\n }, VIDEO_MESH_TIMEOUT * 1000);\n\n this.publicCloudTimer = setTimeout(() => {\n this.publicCloudTimer = undefined;\n\n LoggerProxy.logger.log(\n `Reachability:index#startTimers --> Reachability checks timed out (${DEFAULT_TIMEOUT}s)`\n );\n\n // resolve the promise, so that the client won't be blocked waiting on meetings.register() for too long\n this.resolveReachabilityPromise();\n }, DEFAULT_TIMEOUT * 1000);\n\n this.overallTimer = setTimeout(() => {\n this.overallTimer = undefined;\n this.abortClusterReachability();\n this.emit(\n {\n file: 'reachability',\n function: 'overallTimer timeout',\n },\n 'reachability:done',\n {}\n );\n this.sendMetric();\n\n LoggerProxy.logger.log(\n `Reachability:index#startTimers --> Reachability checks fully timed out (${OVERALL_TIMEOUT}s)`\n );\n }, OVERALL_TIMEOUT * 1000);\n }\n\n /**\n * Stores given reachability results in local storage\n *\n * @param {ReachabilityResults} results\n * @returns {Promise<void>}\n */\n private async storeResults(results: ReachabilityResults) {\n // @ts-ignore\n await this.webex.boundedStorage.put(\n this.namespace,\n REACHABILITY.localStorageResult,\n JSON.stringify(results)\n );\n }\n\n /**\n * Resets all the internal counters that keep track of the results\n *\n * @returns {void}\n */\n private resetResultCounters() {\n this.expectedResultsCount.videoMesh.udp = 0;\n this.expectedResultsCount.public.udp = 0;\n this.expectedResultsCount.public.tcp = 0;\n this.expectedResultsCount.public.xtls = 0;\n\n this.resultsCount.videoMesh.udp = 0;\n this.resultsCount.public.udp = 0;\n this.resultsCount.public.tcp = 0;\n this.resultsCount.public.xtls = 0;\n }\n\n /**\n * Performs reachability checks for all clusters\n * @param {ClusterList} clusterList\n * @returns {Promise<void>} promise that's resolved as soon as the checks are started\n */\n private async performReachabilityChecks(clusterList: ClusterList) {\n const results: ReachabilityResults = {};\n\n this.clusterReachability = {};\n\n if (!clusterList || !Object.keys(clusterList).length) {\n return;\n }\n\n LoggerProxy.logger.log(\n `Reachability:index#performReachabilityChecks --> doing UDP${\n // @ts-ignore\n this.webex.config.meetings.experimental.enableTcpReachability ? ',TCP' : ''\n }${\n // @ts-ignore\n this.webex.config.meetings.experimental.enableTlsReachability ? ',TLS' : ''\n } reachability checks`\n );\n\n this.resetResultCounters();\n this.startTimers();\n\n // sanitize the urls in the clusterList\n Object.keys(clusterList).forEach((key) => {\n const cluster = clusterList[key];\n\n // Linus doesn't support TCP reachability checks on video mesh nodes\n const includeTcpReachability =\n // @ts-ignore\n this.webex.config.meetings.experimental.enableTcpReachability && !cluster.isVideoMesh;\n\n if (!includeTcpReachability) {\n cluster.tcp = [];\n }\n\n // Linus doesn't support xTLS reachability checks on video mesh nodes\n const includeTlsReachability =\n // @ts-ignore\n this.webex.config.meetings.experimental.enableTlsReachability && !cluster.isVideoMesh;\n\n if (!includeTlsReachability) {\n cluster.xtls = [];\n }\n\n // initialize the result for this cluster\n results[key] = {\n udp: {result: cluster.udp.length > 0 ? 'unreachable' : 'untested'},\n tcp: {result: cluster.tcp.length > 0 ? 'unreachable' : 'untested'},\n xtls: {result: cluster.xtls.length > 0 ? 'unreachable' : 'untested'},\n isVideoMesh: cluster.isVideoMesh,\n };\n\n // update expected results counters to include this cluster\n this.expectedResultsCount[cluster.isVideoMesh ? 'videoMesh' : 'public'].udp +=\n cluster.udp.length;\n if (!cluster.isVideoMesh) {\n this.expectedResultsCount.public.tcp += cluster.tcp.length;\n this.expectedResultsCount.public.xtls += cluster.xtls.length;\n }\n });\n\n const isFirstResult = {\n udp: true,\n tcp: true,\n xtls: true,\n };\n\n // save the initialized results (in case we don't get any \"resultReady\" events at all)\n await this.storeResults(results);\n\n // now start the reachability on all the clusters\n Object.keys(clusterList).forEach((key) => {\n const cluster = clusterList[key];\n\n this.clusterReachability[key] = new ClusterReachability(key, cluster);\n this.clusterReachability[key].on(Events.resultReady, async (data: ResultEventData) => {\n const {protocol, result, clientMediaIPs, latencyInMilliseconds} = data;\n\n if (isFirstResult[protocol]) {\n this.emit(\n {\n file: 'reachability',\n function: 'resultReady event handler',\n },\n 'reachability:firstResultAvailable',\n {\n protocol,\n }\n );\n isFirstResult[protocol] = false;\n }\n this.resultsCount[cluster.isVideoMesh ? 'videoMesh' : 'public'][protocol] += 1;\n\n const areAllResultsReady = this.areAllResultsReady();\n\n results[key][protocol].result = result;\n results[key][protocol].clientMediaIPs = clientMediaIPs;\n results[key][protocol].latencyInMilliseconds = latencyInMilliseconds;\n\n await this.storeResults(results);\n\n if (areAllResultsReady) {\n clearTimeout(this.overallTimer);\n this.overallTimer = undefined;\n this.emit(\n {\n file: 'reachability',\n function: 'performReachabilityChecks',\n },\n 'reachability:done',\n {}\n );\n this.sendMetric();\n\n LoggerProxy.logger.log(\n `Reachability:index#gatherReachability --> Reachability checks fully completed`\n );\n this.resolveReachabilityPromise();\n }\n });\n\n // clientMediaIps can be updated independently from the results, so we need to listen for them too\n this.clusterReachability[key].on(\n Events.clientMediaIpsUpdated,\n async (data: ClientMediaIpsUpdatedEventData) => {\n results[key][data.protocol].clientMediaIPs = data.clientMediaIPs;\n\n await this.storeResults(results);\n }\n );\n\n this.clusterReachability[key].start(); // not awaiting on purpose\n });\n }\n}\n"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
3
|
*/
|
|
4
4
|
import { Defer } from '@webex/common';
|
|
5
|
-
import ReachabilityRequest from './request';
|
|
5
|
+
import ReachabilityRequest, { ClusterList } from './request';
|
|
6
6
|
import { ClusterReachability, ClusterReachabilityResult } from './clusterReachability';
|
|
7
7
|
import EventsScope from '../common/events/events-scope';
|
|
8
8
|
export type ReachabilityMetrics = {
|
|
@@ -79,6 +79,16 @@ export default class Reachability extends EventsScope {
|
|
|
79
79
|
* @memberof Reachability
|
|
80
80
|
*/
|
|
81
81
|
constructor(webex: object);
|
|
82
|
+
/**
|
|
83
|
+
* Fetches the list of media clusters from the backend
|
|
84
|
+
* @param {boolean} isRetry
|
|
85
|
+
* @private
|
|
86
|
+
* @returns {Promise<{clusters: ClusterList, joinCookie: any}>}
|
|
87
|
+
*/
|
|
88
|
+
getClusters(isRetry?: boolean): Promise<{
|
|
89
|
+
clusters: ClusterList;
|
|
90
|
+
joinCookie: any;
|
|
91
|
+
}>;
|
|
82
92
|
/**
|
|
83
93
|
* Gets a list of media clusters from the backend and performs reachability checks on all the clusters
|
|
84
94
|
* @returns {Promise<ReachabilityResults>} reachability results
|
package/dist/webinar/index.js
CHANGED
|
@@ -62,7 +62,7 @@ var Webinar = _webexCore.WebexPlugin.extend({
|
|
|
62
62
|
updateCanManageWebcast: function updateCanManageWebcast(canManageWebcast) {
|
|
63
63
|
this.set('canManageWebcast', canManageWebcast);
|
|
64
64
|
},
|
|
65
|
-
version: "3.4.0-next.
|
|
65
|
+
version: "3.4.0-next.6"
|
|
66
66
|
});
|
|
67
67
|
var _default = exports.default = Webinar;
|
|
68
68
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"@webex/eslint-config-legacy": "0.0.0",
|
|
44
44
|
"@webex/jest-config-legacy": "0.0.0",
|
|
45
45
|
"@webex/legacy-tools": "0.0.0",
|
|
46
|
-
"@webex/plugin-meetings": "3.4.0-next.
|
|
46
|
+
"@webex/plugin-meetings": "3.4.0-next.6",
|
|
47
47
|
"@webex/plugin-rooms": "3.4.0-next.1",
|
|
48
48
|
"@webex/test-helper-chai": "3.4.0-next.1",
|
|
49
49
|
"@webex/test-helper-mocha": "3.4.0-next.1",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"@webex/internal-plugin-metrics": "3.4.0-next.1",
|
|
71
71
|
"@webex/internal-plugin-support": "3.4.0-next.1",
|
|
72
72
|
"@webex/internal-plugin-user": "3.4.0-next.1",
|
|
73
|
-
"@webex/internal-plugin-voicea": "3.4.0-next.
|
|
73
|
+
"@webex/internal-plugin-voicea": "3.4.0-next.6",
|
|
74
74
|
"@webex/media-helpers": "3.4.0-next.2",
|
|
75
75
|
"@webex/plugin-people": "3.4.0-next.1",
|
|
76
76
|
"@webex/plugin-rooms": "3.4.0-next.1",
|
|
@@ -91,5 +91,5 @@
|
|
|
91
91
|
"//": [
|
|
92
92
|
"TODO: upgrade jwt-decode when moving to node 18"
|
|
93
93
|
],
|
|
94
|
-
"version": "3.4.0-next.
|
|
94
|
+
"version": "3.4.0-next.6"
|
|
95
95
|
}
|
|
@@ -114,6 +114,32 @@ export default class Reachability extends EventsScope {
|
|
|
114
114
|
this.clusterReachability = {};
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
+
/**
|
|
118
|
+
* Fetches the list of media clusters from the backend
|
|
119
|
+
* @param {boolean} isRetry
|
|
120
|
+
* @private
|
|
121
|
+
* @returns {Promise<{clusters: ClusterList, joinCookie: any}>}
|
|
122
|
+
*/
|
|
123
|
+
async getClusters(isRetry = false): Promise<{clusters: ClusterList; joinCookie: any}> {
|
|
124
|
+
try {
|
|
125
|
+
const {clusters, joinCookie} = await this.reachabilityRequest.getClusters(
|
|
126
|
+
MeetingUtil.getIpVersion(this.webex)
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
return {clusters, joinCookie};
|
|
130
|
+
} catch (error) {
|
|
131
|
+
if (isRetry) {
|
|
132
|
+
throw error;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
LoggerProxy.logger.error(
|
|
136
|
+
`Reachability:index#getClusters --> Failed with error: ${error}, retrying...`
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
return this.getClusters(true);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
117
143
|
/**
|
|
118
144
|
* Gets a list of media clusters from the backend and performs reachability checks on all the clusters
|
|
119
145
|
* @returns {Promise<ReachabilityResults>} reachability results
|
|
@@ -123,9 +149,7 @@ export default class Reachability extends EventsScope {
|
|
|
123
149
|
public async gatherReachability(): Promise<ReachabilityResults> {
|
|
124
150
|
// Fetch clusters and measure latency
|
|
125
151
|
try {
|
|
126
|
-
const {clusters, joinCookie} = await this.
|
|
127
|
-
MeetingUtil.getIpVersion(this.webex)
|
|
128
|
-
);
|
|
152
|
+
const {clusters, joinCookie} = await this.getClusters();
|
|
129
153
|
|
|
130
154
|
// @ts-ignore
|
|
131
155
|
await this.webex.boundedStorage.put(
|
|
@@ -7,7 +7,7 @@ import Reachability, {
|
|
|
7
7
|
ReachabilityResults,
|
|
8
8
|
ReachabilityResultsForBackend,
|
|
9
9
|
} from '@webex/plugin-meetings/src/reachability/';
|
|
10
|
-
import {
|
|
10
|
+
import {ClusterNode} from '../../../../src/reachability/request';
|
|
11
11
|
import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
|
|
12
12
|
import * as ClusterReachabilityModule from '@webex/plugin-meetings/src/reachability/clusterReachability';
|
|
13
13
|
import Metrics from '@webex/plugin-meetings/src/metrics';
|
|
@@ -145,7 +145,6 @@ describe('isAnyPublicClusterReachable', () => {
|
|
|
145
145
|
});
|
|
146
146
|
});
|
|
147
147
|
|
|
148
|
-
|
|
149
148
|
describe('isWebexMediaBackendUnreachable', () => {
|
|
150
149
|
let webex;
|
|
151
150
|
|
|
@@ -1466,6 +1465,70 @@ describe('gatherReachability', () => {
|
|
|
1466
1465
|
xtls: [], // empty list because TLS is disabled in config
|
|
1467
1466
|
});
|
|
1468
1467
|
});
|
|
1468
|
+
|
|
1469
|
+
it('retry of getClusters is succesfull', async () => {
|
|
1470
|
+
webex.config.meetings.experimental = {
|
|
1471
|
+
enableTcpReachability: true,
|
|
1472
|
+
enableTlsReachability: false,
|
|
1473
|
+
};
|
|
1474
|
+
|
|
1475
|
+
const getClustersResult = {
|
|
1476
|
+
clusters: {
|
|
1477
|
+
'cluster name': {
|
|
1478
|
+
udp: ['testUDP1', 'testUDP2'],
|
|
1479
|
+
tcp: ['testTCP1', 'testTCP2'],
|
|
1480
|
+
xtls: ['testXTLS1', 'testXTLS2'],
|
|
1481
|
+
isVideoMesh: false,
|
|
1482
|
+
},
|
|
1483
|
+
},
|
|
1484
|
+
joinCookie: {id: 'id'},
|
|
1485
|
+
};
|
|
1486
|
+
|
|
1487
|
+
const reachability = new Reachability(webex);
|
|
1488
|
+
|
|
1489
|
+
let getClustersCallCount = 0;
|
|
1490
|
+
|
|
1491
|
+
reachability.reachabilityRequest.getClusters = sinon.stub().callsFake(() => {
|
|
1492
|
+
getClustersCallCount++;
|
|
1493
|
+
|
|
1494
|
+
if (getClustersCallCount == 1) {
|
|
1495
|
+
throw new Error('fake error');
|
|
1496
|
+
}
|
|
1497
|
+
|
|
1498
|
+
return getClustersResult;
|
|
1499
|
+
});
|
|
1500
|
+
|
|
1501
|
+
const promise = reachability.gatherReachability();
|
|
1502
|
+
|
|
1503
|
+
await simulateTimeout();
|
|
1504
|
+
await promise;
|
|
1505
|
+
|
|
1506
|
+
assert.equal(getClustersCallCount, 2);
|
|
1507
|
+
|
|
1508
|
+
assert.calledOnce(clusterReachabilityCtorStub);
|
|
1509
|
+
});
|
|
1510
|
+
|
|
1511
|
+
it('two failed calls to getClusters', async () => {
|
|
1512
|
+
const reachability = new Reachability(webex);
|
|
1513
|
+
|
|
1514
|
+
let getClustersCallCount = 0;
|
|
1515
|
+
|
|
1516
|
+
reachability.reachabilityRequest.getClusters = sinon.stub().callsFake(() => {
|
|
1517
|
+
getClustersCallCount++;
|
|
1518
|
+
|
|
1519
|
+
throw new Error('fake error');
|
|
1520
|
+
});
|
|
1521
|
+
|
|
1522
|
+
const promise = reachability.gatherReachability();
|
|
1523
|
+
|
|
1524
|
+
await simulateTimeout();
|
|
1525
|
+
|
|
1526
|
+
await promise;
|
|
1527
|
+
|
|
1528
|
+
assert.equal(getClustersCallCount, 2);
|
|
1529
|
+
|
|
1530
|
+
assert.neverCalledWith(clusterReachabilityCtorStub);
|
|
1531
|
+
});
|
|
1469
1532
|
});
|
|
1470
1533
|
|
|
1471
1534
|
describe('getReachabilityResults', () => {
|