@webex/internal-plugin-metrics 3.0.0-beta.42 → 3.0.0-beta.420

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.
Files changed (73) hide show
  1. package/dist/batcher.js +40 -1
  2. package/dist/batcher.js.map +1 -1
  3. package/dist/call-diagnostic/call-diagnostic-metrics-batcher.js +65 -0
  4. package/dist/call-diagnostic/call-diagnostic-metrics-batcher.js.map +1 -0
  5. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js +552 -0
  6. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js.map +1 -0
  7. package/dist/call-diagnostic/call-diagnostic-metrics.js +863 -0
  8. package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -0
  9. package/dist/call-diagnostic/call-diagnostic-metrics.util.js +371 -0
  10. package/dist/call-diagnostic/call-diagnostic-metrics.util.js.map +1 -0
  11. package/dist/call-diagnostic/config.js +627 -0
  12. package/dist/call-diagnostic/config.js.map +1 -0
  13. package/dist/client-metrics-batcher.js +2 -1
  14. package/dist/client-metrics-batcher.js.map +1 -1
  15. package/dist/config.js +2 -1
  16. package/dist/config.js.map +1 -1
  17. package/dist/index.js +33 -0
  18. package/dist/index.js.map +1 -1
  19. package/dist/metrics.js +27 -28
  20. package/dist/metrics.js.map +1 -1
  21. package/dist/metrics.types.js +7 -0
  22. package/dist/metrics.types.js.map +1 -0
  23. package/dist/new-metrics.js +300 -0
  24. package/dist/new-metrics.js.map +1 -0
  25. package/dist/prelogin-metrics-batcher.js +82 -0
  26. package/dist/prelogin-metrics-batcher.js.map +1 -0
  27. package/dist/types/batcher.d.ts +7 -0
  28. package/dist/types/call-diagnostic/call-diagnostic-metrics-batcher.d.ts +2 -0
  29. package/dist/types/call-diagnostic/call-diagnostic-metrics-latencies.d.ts +237 -0
  30. package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +425 -0
  31. package/dist/types/call-diagnostic/call-diagnostic-metrics.util.d.ts +103 -0
  32. package/dist/types/call-diagnostic/config.d.ts +178 -0
  33. package/dist/types/client-metrics-batcher.d.ts +2 -0
  34. package/dist/types/config.d.ts +36 -0
  35. package/dist/types/index.d.ts +15 -0
  36. package/dist/types/metrics.d.ts +3 -0
  37. package/dist/types/metrics.types.d.ts +107 -0
  38. package/dist/types/new-metrics.d.ts +131 -0
  39. package/dist/types/prelogin-metrics-batcher.d.ts +2 -0
  40. package/dist/types/utils.d.ts +6 -0
  41. package/dist/utils.js +27 -0
  42. package/dist/utils.js.map +1 -0
  43. package/package.json +15 -8
  44. package/src/batcher.js +38 -0
  45. package/src/call-diagnostic/call-diagnostic-metrics-batcher.ts +72 -0
  46. package/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +511 -0
  47. package/src/call-diagnostic/call-diagnostic-metrics.ts +925 -0
  48. package/src/call-diagnostic/call-diagnostic-metrics.util.ts +399 -0
  49. package/src/call-diagnostic/config.ts +685 -0
  50. package/src/client-metrics-batcher.js +1 -0
  51. package/src/config.js +1 -0
  52. package/src/index.ts +56 -0
  53. package/src/metrics.js +21 -24
  54. package/src/metrics.types.ts +179 -0
  55. package/src/new-metrics.ts +278 -0
  56. package/src/prelogin-metrics-batcher.ts +95 -0
  57. package/src/utils.ts +17 -0
  58. package/test/unit/spec/batcher.js +2 -0
  59. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts +469 -0
  60. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +718 -0
  61. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +2371 -0
  62. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +637 -0
  63. package/test/unit/spec/client-metrics-batcher.js +2 -0
  64. package/test/unit/spec/metrics.js +77 -98
  65. package/test/unit/spec/new-metrics.ts +231 -0
  66. package/test/unit/spec/prelogin-metrics-batcher.ts +253 -0
  67. package/test/unit/spec/utils.ts +22 -0
  68. package/tsconfig.json +6 -0
  69. package/dist/call-diagnostic-events-batcher.js +0 -60
  70. package/dist/call-diagnostic-events-batcher.js.map +0 -1
  71. package/src/call-diagnostic-events-batcher.js +0 -62
  72. package/src/index.js +0 -17
  73. package/test/unit/spec/call-diagnostic-events-batcher.js +0 -195
@@ -0,0 +1,552 @@
1
+ "use strict";
2
+
3
+ var _Reflect$construct = require("@babel/runtime-corejs2/core-js/reflect/construct");
4
+ var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
5
+ var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
6
+ _Object$defineProperty(exports, "__esModule", {
7
+ value: true
8
+ });
9
+ exports.default = void 0;
10
+ var _map = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/map"));
11
+ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));
12
+ var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));
13
+ var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/assertThisInitialized"));
14
+ var _inherits2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/inherits"));
15
+ var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/possibleConstructorReturn"));
16
+ var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/getPrototypeOf"));
17
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
18
+ var _webexCore = require("@webex/webex-core");
19
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = _Reflect$construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
20
+ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !_Reflect$construct) return false; if (_Reflect$construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
21
+ // we only care about client event and feature event for now
22
+ /**
23
+ * @description Helper class to store latencies timestamp and to calculate various latencies for CA.
24
+ * @exports
25
+ * @class CallDiagnosticLatencies
26
+ */
27
+ var CallDiagnosticLatencies = /*#__PURE__*/function (_WebexPlugin) {
28
+ (0, _inherits2.default)(CallDiagnosticLatencies, _WebexPlugin);
29
+ var _super = _createSuper(CallDiagnosticLatencies);
30
+ // meetingId that the current latencies are for
31
+
32
+ /**
33
+ * @constructor
34
+ */
35
+ function CallDiagnosticLatencies() {
36
+ var _this;
37
+ (0, _classCallCheck2.default)(this, CallDiagnosticLatencies);
38
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
39
+ args[_key] = arguments[_key];
40
+ }
41
+ _this = _super.call.apply(_super, [this].concat(args));
42
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "latencyTimestamps", void 0);
43
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "precomputedLatencies", void 0);
44
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "meetingId", void 0);
45
+ _this.latencyTimestamps = new _map.default();
46
+ _this.precomputedLatencies = new _map.default();
47
+ return _this;
48
+ }
49
+
50
+ /**
51
+ * Clear timestamps
52
+ */
53
+ (0, _createClass2.default)(CallDiagnosticLatencies, [{
54
+ key: "clearTimestamps",
55
+ value: function clearTimestamps() {
56
+ this.latencyTimestamps.clear();
57
+ this.precomputedLatencies.clear();
58
+ }
59
+
60
+ /**
61
+ * Associate current latencies with a meeting id
62
+ * @param meetingId
63
+ */
64
+ }, {
65
+ key: "setMeetingId",
66
+ value: function setMeetingId(meetingId) {
67
+ this.meetingId = meetingId;
68
+ }
69
+
70
+ /**
71
+ * Returns the meeting object associated with current latencies
72
+ * @returns meeting object
73
+ */
74
+ }, {
75
+ key: "getMeeting",
76
+ value: function getMeeting() {
77
+ if (this.meetingId) {
78
+ // @ts-ignore
79
+ return this.webex.meetings.meetingCollection.get(this.meetingId);
80
+ }
81
+ return undefined;
82
+ }
83
+
84
+ /**
85
+ * Store timestamp value
86
+ * @param key - key
87
+ * @param value - value
88
+ * @param options - store options
89
+ * @throws
90
+ * @returns
91
+ */
92
+ }, {
93
+ key: "saveTimestamp",
94
+ value: function saveTimestamp(_ref) {
95
+ var key = _ref.key,
96
+ _ref$value = _ref.value,
97
+ value = _ref$value === void 0 ? new Date().getTime() : _ref$value,
98
+ _ref$options = _ref.options,
99
+ options = _ref$options === void 0 ? {} : _ref$options;
100
+ // save the meetingId so we can use the meeting object in latency calculations if needed
101
+ var meetingId = options.meetingId;
102
+ if (meetingId) {
103
+ this.setMeetingId(meetingId);
104
+ }
105
+ // for some events we're only interested in the first timestamp not last
106
+ // as these events can happen multiple times
107
+ if (key === 'client.media.rx.start' || key === 'client.media.tx.start' || key === 'internal.client.meetinginfo.request' || key === 'internal.client.meetinginfo.response') {
108
+ this.saveFirstTimestampOnly(key, value);
109
+ } else {
110
+ this.latencyTimestamps.set(key, value);
111
+ }
112
+ }
113
+
114
+ /**
115
+ * Store precomputed latency value
116
+ * @param key - key
117
+ * @param value - value
118
+ * @param accumulate - when it is true, it overwrites existing value with sum of the current value and the new measurement otherwise just store the new measurement
119
+ * @throws
120
+ * @returns
121
+ */
122
+ }, {
123
+ key: "saveLatency",
124
+ value: function saveLatency(key, value) {
125
+ var accumulate = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
126
+ var existingValue = accumulate ? this.precomputedLatencies.get(key) || 0 : 0;
127
+ this.precomputedLatencies.set(key, value + existingValue);
128
+ }
129
+
130
+ /**
131
+ * Measure latency for a request
132
+ * @param callback - callback for which you would like to measure latency
133
+ * @param key - key
134
+ * @param accumulate - when it is true, it overwrites existing value with sum of the current value and the new measurement otherwise just store the new measurement
135
+ * @returns
136
+ */
137
+ }, {
138
+ key: "measureLatency",
139
+ value: function measureLatency(callback, key) {
140
+ var _this2 = this;
141
+ var accumulate = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
142
+ var start = performance.now();
143
+ return callback().finally(function () {
144
+ _this2.saveLatency(key, performance.now() - start, accumulate);
145
+ });
146
+ }
147
+
148
+ /**
149
+ * Store only the first timestamp value for the given key
150
+ * @param key - key
151
+ * @param value -value
152
+ * @throws
153
+ * @returns
154
+ */
155
+ }, {
156
+ key: "saveFirstTimestampOnly",
157
+ value: function saveFirstTimestampOnly(key) {
158
+ var value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Date().getTime();
159
+ if (this.latencyTimestamps.has(key)) {
160
+ return;
161
+ }
162
+ this.latencyTimestamps.set(key, value);
163
+ }
164
+
165
+ /**
166
+ * Helper to calculate end - start
167
+ * @param a start
168
+ * @param b end
169
+ * @returns latency
170
+ */
171
+ }, {
172
+ key: "getDiffBetweenTimestamps",
173
+ value: function getDiffBetweenTimestamps(a, b) {
174
+ var start = this.latencyTimestamps.get(a);
175
+ var end = this.latencyTimestamps.get(b);
176
+ if (start && end) {
177
+ return end - start;
178
+ }
179
+ return undefined;
180
+ }
181
+
182
+ /**
183
+ * Meeting Info Request
184
+ * @note Meeting Info request happen not just in the join phase. CA requires
185
+ * metrics around meeting info request that are only part of join phase.
186
+ * This internal.* event is used to track the real timestamps
187
+ * (when the actual request/response happen). This is because the actual CA event is
188
+ * sent inside the join method on the meeting object based on some logic, but that's not exactly when
189
+ * those events are actually fired. The logic only confirms that they have happened, and we send them over.
190
+ * @returns - latency
191
+ */
192
+ }, {
193
+ key: "getMeetingInfoReqResp",
194
+ value: function getMeetingInfoReqResp() {
195
+ return this.getDiffBetweenTimestamps('internal.client.meetinginfo.request', 'internal.client.meetinginfo.response');
196
+ }
197
+
198
+ /**
199
+ * Interstitial Time
200
+ * @returns - latency
201
+ */
202
+ }, {
203
+ key: "getShowInterstitialTime",
204
+ value: function getShowInterstitialTime() {
205
+ return this.getDiffBetweenTimestamps('client.interstitial-window.start-launch', 'internal.client.interstitial-window.click.joinbutton');
206
+ }
207
+
208
+ /**
209
+ * getU2CTime
210
+ * @returns - latency
211
+ */
212
+ }, {
213
+ key: "getU2CTime",
214
+ value: function getU2CTime() {
215
+ var u2cLatency = this.precomputedLatencies.get('internal.get.u2c.time');
216
+ return u2cLatency ? Math.floor(u2cLatency) : undefined;
217
+ }
218
+
219
+ /**
220
+ * Device Register Time
221
+ * @returns - latency
222
+ */
223
+ }, {
224
+ key: "getRegisterWDMDeviceJMT",
225
+ value: function getRegisterWDMDeviceJMT() {
226
+ return this.getDiffBetweenTimestamps('internal.register.device.request', 'internal.register.device.response');
227
+ }
228
+
229
+ /**
230
+ * Call Init Join Request
231
+ * @returns - latency
232
+ */
233
+ }, {
234
+ key: "getCallInitJoinReq",
235
+ value: function getCallInitJoinReq() {
236
+ return this.getDiffBetweenTimestamps('internal.client.interstitial-window.click.joinbutton', 'client.locus.join.request');
237
+ }
238
+
239
+ /**
240
+ * Locus Join Request
241
+ * @returns - latency
242
+ */
243
+ }, {
244
+ key: "getJoinReqResp",
245
+ value: function getJoinReqResp() {
246
+ return this.getDiffBetweenTimestamps('client.locus.join.request', 'client.locus.join.response');
247
+ }
248
+
249
+ /**
250
+ * Time taken to do turn discovery
251
+ * @returns - latency
252
+ */
253
+ }, {
254
+ key: "getTurnDiscoveryTime",
255
+ value: function getTurnDiscoveryTime() {
256
+ return this.getDiffBetweenTimestamps('internal.client.add-media.turn-discovery.start', 'internal.client.add-media.turn-discovery.end');
257
+ }
258
+
259
+ /**
260
+ * Local SDP Generated Remote SDP REceived
261
+ * @returns - latency
262
+ */
263
+ }, {
264
+ key: "getLocalSDPGenRemoteSDPRecv",
265
+ value: function getLocalSDPGenRemoteSDPRecv() {
266
+ return this.getDiffBetweenTimestamps('client.media-engine.local-sdp-generated', 'client.media-engine.remote-sdp-received');
267
+ }
268
+
269
+ /**
270
+ * ICE Setup Time
271
+ * @returns - latency
272
+ */
273
+ }, {
274
+ key: "getICESetupTime",
275
+ value: function getICESetupTime() {
276
+ return this.getDiffBetweenTimestamps('client.ice.start', 'client.ice.end');
277
+ }
278
+
279
+ /**
280
+ * Audio ICE time
281
+ * @returns - latency
282
+ */
283
+ }, {
284
+ key: "getAudioICESetupTime",
285
+ value: function getAudioICESetupTime() {
286
+ return this.getDiffBetweenTimestamps('client.ice.start', 'client.ice.end');
287
+ }
288
+
289
+ /**
290
+ * Video ICE Time
291
+ * @returns - latency
292
+ */
293
+ }, {
294
+ key: "getVideoICESetupTime",
295
+ value: function getVideoICESetupTime() {
296
+ return this.getDiffBetweenTimestamps('client.ice.start', 'client.ice.end');
297
+ }
298
+
299
+ /**
300
+ * Share ICE Time
301
+ * @returns - latency
302
+ */
303
+ }, {
304
+ key: "getShareICESetupTime",
305
+ value: function getShareICESetupTime() {
306
+ return this.getDiffBetweenTimestamps('client.ice.start', 'client.ice.end');
307
+ }
308
+
309
+ /**
310
+ * Stay Lobby Time
311
+ * @returns - latency
312
+ */
313
+ }, {
314
+ key: "getStayLobbyTime",
315
+ value: function getStayLobbyTime() {
316
+ return this.getDiffBetweenTimestamps('client.locus.join.response', 'internal.host.meeting.participant.admitted');
317
+ }
318
+
319
+ /**
320
+ * Page JMT
321
+ * @returns - latency
322
+ */
323
+ }, {
324
+ key: "getPageJMT",
325
+ value: function getPageJMT() {
326
+ return this.precomputedLatencies.get('internal.client.pageJMT') || undefined;
327
+ }
328
+
329
+ /**
330
+ * Download Time JMT
331
+ * @returns - latency
332
+ */
333
+ }, {
334
+ key: "getDownloadTimeJMT",
335
+ value: function getDownloadTimeJMT() {
336
+ return this.precomputedLatencies.get('internal.download.time') || undefined;
337
+ }
338
+
339
+ /**
340
+ * Click To Interstitial
341
+ * @returns - latency
342
+ */
343
+ }, {
344
+ key: "getClickToInterstitial",
345
+ value: function getClickToInterstitial() {
346
+ // for normal join (where green join button exists before interstitial, i.e reminder, space list etc)
347
+ if (this.latencyTimestamps.get('internal.client.meeting.click.joinbutton')) {
348
+ return this.getDiffBetweenTimestamps('internal.client.meeting.click.joinbutton', 'internal.client.meeting.interstitial-window.showed');
349
+ }
350
+
351
+ // for cross launch and guest flows
352
+ return this.precomputedLatencies.get('internal.click.to.interstitial') || undefined;
353
+ }
354
+
355
+ /**
356
+ * Interstitial To Join Ok
357
+ * @returns - latency
358
+ */
359
+ }, {
360
+ key: "getInterstitialToJoinOK",
361
+ value: function getInterstitialToJoinOK() {
362
+ return this.getDiffBetweenTimestamps('internal.client.interstitial-window.click.joinbutton', 'client.locus.join.response');
363
+ }
364
+
365
+ /**
366
+ * Call Init To MediaEngineReady
367
+ * @returns - latency
368
+ */
369
+ }, {
370
+ key: "getCallInitMediaEngineReady",
371
+ value: function getCallInitMediaEngineReady() {
372
+ return this.getDiffBetweenTimestamps('internal.client.interstitial-window.click.joinbutton', 'client.media-engine.ready');
373
+ }
374
+
375
+ /**
376
+ * Interstitial To Media Ok
377
+ * @returns - latency
378
+ */
379
+ }, {
380
+ key: "getInterstitialToMediaOKJMT",
381
+ value: function getInterstitialToMediaOKJMT() {
382
+ var interstitialJoinClickTimestamp = this.latencyTimestamps.get('internal.client.interstitial-window.click.joinbutton');
383
+
384
+ // get the first timestamp
385
+ var connectedMedia = this.latencyTimestamps.get('client.ice.end');
386
+ var lobbyTime = this.getStayLobbyTime() || 0;
387
+ if (interstitialJoinClickTimestamp && connectedMedia) {
388
+ return connectedMedia - interstitialJoinClickTimestamp - lobbyTime;
389
+ }
390
+ return undefined;
391
+ }
392
+
393
+ /**
394
+ * Total JMT
395
+ * @returns - latency
396
+ */
397
+ }, {
398
+ key: "getTotalJMT",
399
+ value: function getTotalJMT() {
400
+ var clickToInterstitial = this.getClickToInterstitial();
401
+ var interstitialToJoinOk = this.getInterstitialToJoinOK();
402
+ if (clickToInterstitial && interstitialToJoinOk) {
403
+ return clickToInterstitial + interstitialToJoinOk;
404
+ }
405
+ return undefined;
406
+ }
407
+
408
+ /**
409
+ * Join Conf JMT
410
+ * @returns - latency
411
+ */
412
+ }, {
413
+ key: "getJoinConfJMT",
414
+ value: function getJoinConfJMT() {
415
+ var joinReqResp = this.getJoinReqResp();
416
+ var ICESetupTime = this.getICESetupTime();
417
+ if (joinReqResp && ICESetupTime) {
418
+ return joinReqResp + ICESetupTime;
419
+ }
420
+ return undefined;
421
+ }
422
+
423
+ /**
424
+ * Total Media JMT
425
+ * @returns - latency
426
+ */
427
+ }, {
428
+ key: "getTotalMediaJMT",
429
+ value: function getTotalMediaJMT() {
430
+ var clickToInterstitial = this.getClickToInterstitial();
431
+ var interstitialToJoinOk = this.getInterstitialToJoinOK();
432
+ var joinConfJMT = this.getJoinConfJMT();
433
+ var lobbyTime = this.getStayLobbyTime();
434
+ if (clickToInterstitial && interstitialToJoinOk && joinConfJMT) {
435
+ var _this$getMeeting;
436
+ var totalMediaJMT = clickToInterstitial + interstitialToJoinOk + joinConfJMT;
437
+ if ((_this$getMeeting = this.getMeeting()) !== null && _this$getMeeting !== void 0 && _this$getMeeting.allowMediaInLobby) {
438
+ return totalMediaJMT;
439
+ }
440
+ return totalMediaJMT - lobbyTime;
441
+ }
442
+ return undefined;
443
+ }
444
+
445
+ /**
446
+ * Client JMT
447
+ * @returns - latency
448
+ */
449
+ }, {
450
+ key: "getClientJMT",
451
+ value: function getClientJMT() {
452
+ var interstitialToJoinOk = this.getInterstitialToJoinOK();
453
+ var joinConfJMT = this.getJoinConfJMT();
454
+ if (interstitialToJoinOk && joinConfJMT) {
455
+ return interstitialToJoinOk - joinConfJMT;
456
+ }
457
+ return undefined;
458
+ }
459
+
460
+ /**
461
+ * Audio setup delay receive
462
+ */
463
+ }, {
464
+ key: "getAudioJoinRespRxStart",
465
+ value: function getAudioJoinRespRxStart() {
466
+ return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.media.rx.start');
467
+ }
468
+
469
+ /**
470
+ * Video setup delay receive
471
+ */
472
+ }, {
473
+ key: "getVideoJoinRespRxStart",
474
+ value: function getVideoJoinRespRxStart() {
475
+ return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.media.rx.start');
476
+ }
477
+
478
+ /**
479
+ * Total latency for all get cluster request.
480
+ */
481
+ }, {
482
+ key: "getReachabilityClustersReqResp",
483
+ value: function getReachabilityClustersReqResp() {
484
+ var reachablityClusterReqResp = this.precomputedLatencies.get('internal.get.cluster.time');
485
+ return reachablityClusterReqResp ? Math.floor(reachablityClusterReqResp) : undefined;
486
+ }
487
+
488
+ /**
489
+ * Audio setup delay transmit
490
+ */
491
+ }, {
492
+ key: "getAudioJoinRespTxStart",
493
+ value: function getAudioJoinRespTxStart() {
494
+ return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.media.tx.start');
495
+ }
496
+
497
+ /**
498
+ * Video setup delay transmit
499
+ */
500
+ }, {
501
+ key: "getVideoJoinRespTxStart",
502
+ value: function getVideoJoinRespTxStart() {
503
+ return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.media.tx.start');
504
+ }
505
+
506
+ /**
507
+ * Total latency for all exchange ci token.
508
+ */
509
+ }, {
510
+ key: "getExchangeCITokenJMT",
511
+ value: function getExchangeCITokenJMT() {
512
+ var exchangeCITokenJMT = this.precomputedLatencies.get('internal.exchange.ci.token.time');
513
+ return exchangeCITokenJMT ? Math.floor(exchangeCITokenJMT) : undefined;
514
+ }
515
+
516
+ /**
517
+ * Total latency for all refresh captcha requests.
518
+ */
519
+ }, {
520
+ key: "getRefreshCaptchaReqResp",
521
+ value: function getRefreshCaptchaReqResp() {
522
+ var refreshCaptchaReqResp = this.precomputedLatencies.get('internal.refresh.captcha.time');
523
+ return refreshCaptchaReqResp ? Math.floor(refreshCaptchaReqResp) : undefined;
524
+ }
525
+
526
+ /**
527
+ * Get the latency for downloading intelligence models.
528
+ * @returns - latency
529
+ */
530
+ }, {
531
+ key: "getDownloadIntelligenceModelsReqResp",
532
+ value: function getDownloadIntelligenceModelsReqResp() {
533
+ var downloadIntelligenceModelsReqResp = this.precomputedLatencies.get('internal.api.fetch.intelligence.models');
534
+ return downloadIntelligenceModelsReqResp ? Math.floor(downloadIntelligenceModelsReqResp) : undefined;
535
+ }
536
+
537
+ /**
538
+ * Get the total latency for all other app API requests.
539
+ * Excludes meeting info, because it's measured separately.
540
+ * @returns - latency
541
+ */
542
+ }, {
543
+ key: "getOtherAppApiReqResp",
544
+ value: function getOtherAppApiReqResp() {
545
+ var otherAppApiJMT = this.precomputedLatencies.get('internal.other.app.api.time');
546
+ return otherAppApiJMT > 0 ? Math.floor(otherAppApiJMT) : undefined;
547
+ }
548
+ }]);
549
+ return CallDiagnosticLatencies;
550
+ }(_webexCore.WebexPlugin);
551
+ exports.default = CallDiagnosticLatencies;
552
+ //# sourceMappingURL=call-diagnostic-metrics-latencies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["CallDiagnosticLatencies","args","latencyTimestamps","precomputedLatencies","clear","meetingId","webex","meetings","meetingCollection","get","undefined","key","value","Date","getTime","options","setMeetingId","saveFirstTimestampOnly","set","accumulate","existingValue","callback","start","performance","now","finally","saveLatency","has","a","b","end","getDiffBetweenTimestamps","u2cLatency","Math","floor","interstitialJoinClickTimestamp","connectedMedia","lobbyTime","getStayLobbyTime","clickToInterstitial","getClickToInterstitial","interstitialToJoinOk","getInterstitialToJoinOK","joinReqResp","getJoinReqResp","ICESetupTime","getICESetupTime","joinConfJMT","getJoinConfJMT","totalMediaJMT","getMeeting","allowMediaInLobby","reachablityClusterReqResp","exchangeCITokenJMT","refreshCaptchaReqResp","downloadIntelligenceModelsReqResp","otherAppApiJMT","WebexPlugin"],"sources":["call-diagnostic-metrics-latencies.ts"],"sourcesContent":["/* eslint-disable class-methods-use-this */\n/* eslint-disable valid-jsdoc */\nimport {WebexPlugin} from '@webex/webex-core';\n\nimport {MetricEventNames, PreComputedLatencies} from '../metrics.types';\n\n// we only care about client event and feature event for now\n\n/**\n * @description Helper class to store latencies timestamp and to calculate various latencies for CA.\n * @exports\n * @class CallDiagnosticLatencies\n */\nexport default class CallDiagnosticLatencies extends WebexPlugin {\n latencyTimestamps: Map<MetricEventNames, number>;\n precomputedLatencies: Map<PreComputedLatencies, number>;\n // meetingId that the current latencies are for\n private meetingId?: string;\n\n /**\n * @constructor\n */\n constructor(...args) {\n super(...args);\n this.latencyTimestamps = new Map();\n this.precomputedLatencies = new Map();\n }\n\n /**\n * Clear timestamps\n */\n public clearTimestamps() {\n this.latencyTimestamps.clear();\n this.precomputedLatencies.clear();\n }\n\n /**\n * Associate current latencies with a meeting id\n * @param meetingId\n */\n private setMeetingId(meetingId: string) {\n this.meetingId = meetingId;\n }\n\n /**\n * Returns the meeting object associated with current latencies\n * @returns meeting object\n */\n private getMeeting() {\n if (this.meetingId) {\n // @ts-ignore\n return this.webex.meetings.meetingCollection.get(this.meetingId);\n }\n\n return undefined;\n }\n\n /**\n * Store timestamp value\n * @param key - key\n * @param value - value\n * @param options - store options\n * @throws\n * @returns\n */\n public saveTimestamp({\n key,\n value = new Date().getTime(),\n options = {},\n }: {\n key: MetricEventNames;\n value?: number;\n options?: {meetingId?: string};\n }) {\n // save the meetingId so we can use the meeting object in latency calculations if needed\n const {meetingId} = options;\n if (meetingId) {\n this.setMeetingId(meetingId);\n }\n // for some events we're only interested in the first timestamp not last\n // as these events can happen multiple times\n if (\n key === 'client.media.rx.start' ||\n key === 'client.media.tx.start' ||\n key === 'internal.client.meetinginfo.request' ||\n key === 'internal.client.meetinginfo.response'\n ) {\n this.saveFirstTimestampOnly(key, value);\n } else {\n this.latencyTimestamps.set(key, value);\n }\n }\n\n /**\n * Store precomputed latency value\n * @param key - key\n * @param value - value\n * @param accumulate - when it is true, it overwrites existing value with sum of the current value and the new measurement otherwise just store the new measurement\n * @throws\n * @returns\n */\n public saveLatency(key: PreComputedLatencies, value: number, accumulate = false) {\n const existingValue = accumulate ? this.precomputedLatencies.get(key) || 0 : 0;\n this.precomputedLatencies.set(key, value + existingValue);\n }\n\n /**\n * Measure latency for a request\n * @param callback - callback for which you would like to measure latency\n * @param key - key\n * @param accumulate - when it is true, it overwrites existing value with sum of the current value and the new measurement otherwise just store the new measurement\n * @returns\n */\n public measureLatency(\n callback: () => Promise<unknown>,\n key: PreComputedLatencies,\n accumulate = false\n ) {\n const start = performance.now();\n\n return callback().finally(() => {\n this.saveLatency(key, performance.now() - start, accumulate);\n });\n }\n\n /**\n * Store only the first timestamp value for the given key\n * @param key - key\n * @param value -value\n * @throws\n * @returns\n */\n saveFirstTimestampOnly(key: MetricEventNames, value: number = new Date().getTime()) {\n if (this.latencyTimestamps.has(key)) {\n return;\n }\n this.latencyTimestamps.set(key, value);\n }\n\n /**\n * Helper to calculate end - start\n * @param a start\n * @param b end\n * @returns latency\n */\n public getDiffBetweenTimestamps(a: MetricEventNames, b: MetricEventNames) {\n const start = this.latencyTimestamps.get(a);\n const end = this.latencyTimestamps.get(b);\n if (start && end) {\n return end - start;\n }\n\n return undefined;\n }\n\n /**\n * Meeting Info Request\n * @note Meeting Info request happen not just in the join phase. CA requires\n * metrics around meeting info request that are only part of join phase.\n * This internal.* event is used to track the real timestamps\n * (when the actual request/response happen). This is because the actual CA event is\n * sent inside the join method on the meeting object based on some logic, but that's not exactly when\n * those events are actually fired. The logic only confirms that they have happened, and we send them over.\n * @returns - latency\n */\n public getMeetingInfoReqResp() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.meetinginfo.request',\n 'internal.client.meetinginfo.response'\n );\n }\n\n /**\n * Interstitial Time\n * @returns - latency\n */\n public getShowInterstitialTime() {\n return this.getDiffBetweenTimestamps(\n 'client.interstitial-window.start-launch',\n 'internal.client.interstitial-window.click.joinbutton'\n );\n }\n\n /**\n * getU2CTime\n * @returns - latency\n */\n public getU2CTime() {\n const u2cLatency = this.precomputedLatencies.get('internal.get.u2c.time');\n\n return u2cLatency ? Math.floor(u2cLatency) : undefined;\n }\n\n /**\n * Device Register Time\n * @returns - latency\n */\n public getRegisterWDMDeviceJMT() {\n return this.getDiffBetweenTimestamps(\n 'internal.register.device.request',\n 'internal.register.device.response'\n );\n }\n\n /**\n * Call Init Join Request\n * @returns - latency\n */\n public getCallInitJoinReq() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.interstitial-window.click.joinbutton',\n 'client.locus.join.request'\n );\n }\n\n /**\n * Locus Join Request\n * @returns - latency\n */\n public getJoinReqResp() {\n return this.getDiffBetweenTimestamps('client.locus.join.request', 'client.locus.join.response');\n }\n\n /**\n * Time taken to do turn discovery\n * @returns - latency\n */\n public getTurnDiscoveryTime() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.add-media.turn-discovery.start',\n 'internal.client.add-media.turn-discovery.end'\n );\n }\n\n /**\n * Local SDP Generated Remote SDP REceived\n * @returns - latency\n */\n public getLocalSDPGenRemoteSDPRecv() {\n return this.getDiffBetweenTimestamps(\n 'client.media-engine.local-sdp-generated',\n 'client.media-engine.remote-sdp-received'\n );\n }\n\n /**\n * ICE Setup Time\n * @returns - latency\n */\n public getICESetupTime() {\n return this.getDiffBetweenTimestamps('client.ice.start', 'client.ice.end');\n }\n\n /**\n * Audio ICE time\n * @returns - latency\n */\n public getAudioICESetupTime() {\n return this.getDiffBetweenTimestamps('client.ice.start', 'client.ice.end');\n }\n\n /**\n * Video ICE Time\n * @returns - latency\n */\n public getVideoICESetupTime() {\n return this.getDiffBetweenTimestamps('client.ice.start', 'client.ice.end');\n }\n\n /**\n * Share ICE Time\n * @returns - latency\n */\n public getShareICESetupTime() {\n return this.getDiffBetweenTimestamps('client.ice.start', 'client.ice.end');\n }\n\n /**\n * Stay Lobby Time\n * @returns - latency\n */\n public getStayLobbyTime() {\n return this.getDiffBetweenTimestamps(\n 'client.locus.join.response',\n 'internal.host.meeting.participant.admitted'\n );\n }\n\n /**\n * Page JMT\n * @returns - latency\n */\n public getPageJMT() {\n return this.precomputedLatencies.get('internal.client.pageJMT') || undefined;\n }\n\n /**\n * Download Time JMT\n * @returns - latency\n */\n public getDownloadTimeJMT() {\n return this.precomputedLatencies.get('internal.download.time') || undefined;\n }\n\n /**\n * Click To Interstitial\n * @returns - latency\n */\n public getClickToInterstitial() {\n // for normal join (where green join button exists before interstitial, i.e reminder, space list etc)\n if (this.latencyTimestamps.get('internal.client.meeting.click.joinbutton')) {\n return this.getDiffBetweenTimestamps(\n 'internal.client.meeting.click.joinbutton',\n 'internal.client.meeting.interstitial-window.showed'\n );\n }\n\n // for cross launch and guest flows\n return this.precomputedLatencies.get('internal.click.to.interstitial') || undefined;\n }\n\n /**\n * Interstitial To Join Ok\n * @returns - latency\n */\n public getInterstitialToJoinOK() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.interstitial-window.click.joinbutton',\n 'client.locus.join.response'\n );\n }\n\n /**\n * Call Init To MediaEngineReady\n * @returns - latency\n */\n public getCallInitMediaEngineReady() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.interstitial-window.click.joinbutton',\n 'client.media-engine.ready'\n );\n }\n\n /**\n * Interstitial To Media Ok\n * @returns - latency\n */\n public getInterstitialToMediaOKJMT() {\n const interstitialJoinClickTimestamp = this.latencyTimestamps.get(\n 'internal.client.interstitial-window.click.joinbutton'\n );\n\n // get the first timestamp\n const connectedMedia = this.latencyTimestamps.get('client.ice.end');\n\n const lobbyTime = this.getStayLobbyTime() || 0;\n\n if (interstitialJoinClickTimestamp && connectedMedia) {\n return connectedMedia - interstitialJoinClickTimestamp - lobbyTime;\n }\n\n return undefined;\n }\n\n /**\n * Total JMT\n * @returns - latency\n */\n public getTotalJMT() {\n const clickToInterstitial = this.getClickToInterstitial();\n const interstitialToJoinOk = this.getInterstitialToJoinOK();\n\n if (clickToInterstitial && interstitialToJoinOk) {\n return clickToInterstitial + interstitialToJoinOk;\n }\n\n return undefined;\n }\n\n /**\n * Join Conf JMT\n * @returns - latency\n */\n public getJoinConfJMT() {\n const joinReqResp = this.getJoinReqResp();\n const ICESetupTime = this.getICESetupTime();\n\n if (joinReqResp && ICESetupTime) {\n return joinReqResp + ICESetupTime;\n }\n\n return undefined;\n }\n\n /**\n * Total Media JMT\n * @returns - latency\n */\n public getTotalMediaJMT() {\n const clickToInterstitial = this.getClickToInterstitial();\n const interstitialToJoinOk = this.getInterstitialToJoinOK();\n const joinConfJMT = this.getJoinConfJMT();\n const lobbyTime = this.getStayLobbyTime();\n\n if (clickToInterstitial && interstitialToJoinOk && joinConfJMT) {\n const totalMediaJMT = clickToInterstitial + interstitialToJoinOk + joinConfJMT;\n if (this.getMeeting()?.allowMediaInLobby) {\n return totalMediaJMT;\n }\n\n return totalMediaJMT - lobbyTime;\n }\n\n return undefined;\n }\n\n /**\n * Client JMT\n * @returns - latency\n */\n public getClientJMT() {\n const interstitialToJoinOk = this.getInterstitialToJoinOK();\n const joinConfJMT = this.getJoinConfJMT();\n\n if (interstitialToJoinOk && joinConfJMT) {\n return interstitialToJoinOk - joinConfJMT;\n }\n\n return undefined;\n }\n\n /**\n * Audio setup delay receive\n */\n public getAudioJoinRespRxStart() {\n return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.media.rx.start');\n }\n\n /**\n * Video setup delay receive\n */\n public getVideoJoinRespRxStart() {\n return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.media.rx.start');\n }\n\n /**\n * Total latency for all get cluster request.\n */\n public getReachabilityClustersReqResp() {\n const reachablityClusterReqResp = this.precomputedLatencies.get('internal.get.cluster.time');\n\n return reachablityClusterReqResp ? Math.floor(reachablityClusterReqResp) : undefined;\n }\n\n /**\n * Audio setup delay transmit\n */\n public getAudioJoinRespTxStart() {\n return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.media.tx.start');\n }\n\n /**\n * Video setup delay transmit\n */\n public getVideoJoinRespTxStart() {\n return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.media.tx.start');\n }\n\n /**\n * Total latency for all exchange ci token.\n */\n public getExchangeCITokenJMT() {\n const exchangeCITokenJMT = this.precomputedLatencies.get('internal.exchange.ci.token.time');\n\n return exchangeCITokenJMT ? Math.floor(exchangeCITokenJMT) : undefined;\n }\n\n /**\n * Total latency for all refresh captcha requests.\n */\n public getRefreshCaptchaReqResp() {\n const refreshCaptchaReqResp = this.precomputedLatencies.get('internal.refresh.captcha.time');\n\n return refreshCaptchaReqResp ? Math.floor(refreshCaptchaReqResp) : undefined;\n }\n\n /**\n * Get the latency for downloading intelligence models.\n * @returns - latency\n */\n public getDownloadIntelligenceModelsReqResp() {\n const downloadIntelligenceModelsReqResp = this.precomputedLatencies.get(\n 'internal.api.fetch.intelligence.models'\n );\n\n return downloadIntelligenceModelsReqResp\n ? Math.floor(downloadIntelligenceModelsReqResp)\n : undefined;\n }\n\n /**\n * Get the total latency for all other app API requests.\n * Excludes meeting info, because it's measured separately.\n * @returns - latency\n */\n public getOtherAppApiReqResp() {\n const otherAppApiJMT = this.precomputedLatencies.get('internal.other.app.api.time');\n\n return otherAppApiJMT > 0 ? Math.floor(otherAppApiJMT) : undefined;\n }\n}\n"],"mappings":"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"}