@webex/internal-plugin-metrics 3.12.0-next.5 → 3.12.0-next.7

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.
@@ -335,6 +335,27 @@ var CallDiagnosticLatencies = exports.default = /*#__PURE__*/function (_WebexPlu
335
335
  return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.lobby.exited');
336
336
  }
337
337
 
338
+ /**
339
+ * Stay lobby time capped by a certain timestamp.
340
+ * This is to handle the case where the target end timestamp could happen before the lobby is exited,
341
+ * for example media-engine.ready or client.ice.end
342
+ * @param endTimestampKey name of the target end event
343
+ * @returns - latency
344
+ */
345
+ }, {
346
+ key: "getStayLobbyTimeCappedBy",
347
+ value: function getStayLobbyTimeCappedBy(endTimestampKey) {
348
+ var lobbyStartTimestamp = this.latencyTimestamps.get('client.locus.join.response'); // must exist
349
+ var lobbyEndTimestamp = this.latencyTimestamps.get('client.lobby.exited'); // might not exist
350
+ var maximumEndTimestamp = this.latencyTimestamps.get(endTimestampKey); // must exist
351
+
352
+ if (typeof lobbyStartTimestamp !== 'number' || typeof maximumEndTimestamp !== 'number') {
353
+ return undefined;
354
+ }
355
+ var endTimestamp = typeof lobbyEndTimestamp === 'number' ? Math.min(lobbyEndTimestamp, maximumEndTimestamp) : maximumEndTimestamp;
356
+ return (0, _lodash.clamp)(endTimestamp - lobbyStartTimestamp, 0, this.MAX_INTEGER);
357
+ }
358
+
338
359
  /**
339
360
  * Page JMT
340
361
  * @returns - latency
@@ -410,9 +431,7 @@ var CallDiagnosticLatencies = exports.default = /*#__PURE__*/function (_WebexPlu
410
431
  }, {
411
432
  key: "getCallInitMediaEngineReady",
412
433
  value: function getCallInitMediaEngineReady() {
413
- return this.getDiffBetweenTimestamps('internal.client.interstitial-window.click.joinbutton', 'client.media-engine.ready', {
414
- maximum: 1200000
415
- });
434
+ return this.getInterstitialToMediaOKJMT();
416
435
  }
417
436
 
418
437
  /**
@@ -422,15 +441,10 @@ var CallDiagnosticLatencies = exports.default = /*#__PURE__*/function (_WebexPlu
422
441
  }, {
423
442
  key: "getInterstitialToMediaOKJMT",
424
443
  value: function getInterstitialToMediaOKJMT() {
425
- var interstitialJoinClickTimestamp = this.latencyTimestamps.get('internal.client.interstitial-window.click.joinbutton');
426
-
427
- // get the first timestamp
428
- var connectedMedia = this.latencyTimestamps.get('client.ice.end');
429
- var lobbyTimeLatency = this.getStayLobbyTime();
430
- var lobbyTime = typeof lobbyTimeLatency === 'number' ? lobbyTimeLatency : 0;
431
- if (interstitialJoinClickTimestamp && connectedMedia) {
432
- var interstitialToMediaOKJmt = connectedMedia - interstitialJoinClickTimestamp - lobbyTime;
433
- return (0, _lodash.clamp)(interstitialToMediaOKJmt, 0, this.MAX_INTEGER);
444
+ var interstitialClickJoinToIceEnd = this.getDiffBetweenTimestamps('internal.client.interstitial-window.click.joinbutton', 'client.ice.end');
445
+ var stayLobbyTimeCappedByIceEnd = this.getStayLobbyTimeCappedBy('client.ice.end');
446
+ if (typeof interstitialClickJoinToIceEnd === 'number' && typeof stayLobbyTimeCappedByIceEnd === 'number') {
447
+ return (0, _lodash.clamp)(interstitialClickJoinToIceEnd - stayLobbyTimeCappedByIceEnd, 0, this.MAX_INTEGER);
434
448
  }
435
449
  return undefined;
436
450
  }
@@ -488,17 +502,10 @@ var CallDiagnosticLatencies = exports.default = /*#__PURE__*/function (_WebexPlu
488
502
  key: "getTotalMediaJMT",
489
503
  value: function getTotalMediaJMT() {
490
504
  var clickToInterstitial = this.getClickToInterstitial();
491
- var interstitialToJoinOk = this.getInterstitialToJoinOK();
492
- var joinConfJMT = this.getJoinConfJMT();
493
- var lobbyTimeLatency = this.getStayLobbyTime();
494
- var lobbyTime = typeof lobbyTimeLatency === 'number' ? lobbyTimeLatency : 0;
495
- if (clickToInterstitial && interstitialToJoinOk && joinConfJMT) {
496
- var _this$getMeeting;
497
- var totalMediaJMT = (0, _lodash.clamp)(clickToInterstitial + interstitialToJoinOk + joinConfJMT, 0, Infinity);
498
- if ((_this$getMeeting = this.getMeeting()) !== null && _this$getMeeting !== void 0 && _this$getMeeting.allowMediaInLobby) {
499
- return (0, _lodash.clamp)(totalMediaJMT, 0, this.MAX_INTEGER);
500
- }
501
- return (0, _lodash.clamp)(totalMediaJMT - lobbyTime, 0, this.MAX_INTEGER);
505
+ var interstitialClickJoinToMediaEngineReady = this.getDiffBetweenTimestamps('internal.client.interstitial-window.click.joinbutton', 'client.media-engine.ready');
506
+ var stayLobbyTimeCappedByMediaEngineReady = this.getStayLobbyTimeCappedBy('client.media-engine.ready');
507
+ if (typeof clickToInterstitial === 'number' && typeof interstitialClickJoinToMediaEngineReady === 'number' && typeof stayLobbyTimeCappedByMediaEngineReady === 'number') {
508
+ return (0, _lodash.clamp)(clickToInterstitial + interstitialClickJoinToMediaEngineReady - stayLobbyTimeCappedByMediaEngineReady, 0, this.MAX_INTEGER);
502
509
  }
503
510
  return undefined;
504
511
  }
@@ -511,10 +518,9 @@ var CallDiagnosticLatencies = exports.default = /*#__PURE__*/function (_WebexPlu
511
518
  key: "getTotalMediaJMTWithUserDelay",
512
519
  value: function getTotalMediaJMTWithUserDelay() {
513
520
  var clickToInterstitialWithUserDelay = this.getClickToInterstitialWithUserDelay();
514
- var interstitialToJoinOk = this.getInterstitialToJoinOK();
515
- var joinConfJMT = this.getJoinConfJMT();
516
- if (clickToInterstitialWithUserDelay && interstitialToJoinOk && joinConfJMT) {
517
- return (0, _lodash.clamp)(clickToInterstitialWithUserDelay + interstitialToJoinOk + joinConfJMT, 0, this.MAX_INTEGER);
521
+ var interstitialShowedToMediaEngineReady = this.getDiffBetweenTimestamps('internal.client.meeting.interstitial-window.showed', 'client.media-engine.ready');
522
+ if (typeof clickToInterstitialWithUserDelay === 'number' && typeof interstitialShowedToMediaEngineReady === 'number') {
523
+ return (0, _lodash.clamp)(clickToInterstitialWithUserDelay + interstitialShowedToMediaEngineReady, 0, this.MAX_INTEGER);
518
524
  }
519
525
  return undefined;
520
526
  }
@@ -1 +1 @@
1
- {"version":3,"names":["_webexCore","require","_lodash","_callSuper","t","o","e","_getPrototypeOf2","default","_possibleConstructorReturn2","_isNativeReflectConstruct","_Reflect$construct","constructor","apply","Boolean","prototype","valueOf","call","CallDiagnosticLatencies","exports","_WebexPlugin","_this","_classCallCheck2","_len","arguments","length","args","Array","_key","concat","_defineProperty2","latencyTimestamps","_map","precomputedLatencies","_inherits2","_createClass2","key","value","clearTimestamps","clear","setMeetingId","meetingId","getMeeting","webex","meetings","getBasicMeetingInformation","undefined","saveTimestamp","_ref","_ref$value","Date","getTime","_ref$options","options","saveFirstTimestampOnly","set","delete","saveLatency","accumulate","existingValue","get","measureLatency","callback","_this2","start","performance","now","finally","has","getDiffBetweenTimestamps","a","b","clampValues","end","diff","_ref2","_ref2$minimum","minimum","_ref2$maximum","maximum","MAX_INTEGER","clamp","getMeetingInfoReqResp","getShowInterstitialTime","getU2CTime","u2cLatency","Math","floor","getRegisterWDMDeviceJMT","getCallInitJoinReq","getJoinReqResp","getTurnDiscoveryTime","getLocalSDPGenRemoteSDPRecv","getICESetupTime","getAudioICESetupTime","getVideoICESetupTime","getShareICESetupTime","getStayLobbyTime","getPageJMT","latency","getDownloadTimeJMT","getClickToInterstitial","clickToInterstitialLatency","getClickToInterstitialWithUserDelay","clickToInterstitialWithUserDelayLatency","getInterstitialToJoinOK","getCallInitMediaEngineReady","getInterstitialToMediaOKJMT","interstitialJoinClickTimestamp","connectedMedia","lobbyTimeLatency","lobbyTime","interstitialToMediaOKJmt","getTotalJMT","clickToInterstitial","interstitialClickJoinToJoinLocusResponse","getTotalJMTWithUserDelay","clickToInterstitialWithUserDelay","interstitialShowedToJoinLocusResponse","getJoinConfJMT","joinReqResp","ICESetupTime","getTotalMediaJMT","interstitialToJoinOk","joinConfJMT","_this$getMeeting","totalMediaJMT","Infinity","allowMediaInLobby","getTotalMediaJMTWithUserDelay","getClientJMT","getAudioJoinRespRxStart","getVideoJoinRespRxStart","getReachabilityClustersReqResp","reachablityClusterReqResp","getAudioJoinRespTxStart","getVideoJoinRespTxStart","getShareDuration","getExchangeCITokenJMT","exchangeCITokenJMT","getRefreshCaptchaReqResp","refreshCaptchaReqResp","getDownloadIntelligenceModelsReqResp","downloadIntelligenceModelsReqResp","getOtherAppApiReqResp","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';\nimport {clamp} from 'lodash';\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 private MAX_INTEGER = 2147483647;\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.getBasicMeetingInformation(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 key === 'client.media-engine.remote-sdp-received'\n ) {\n this.saveFirstTimestampOnly(key, value);\n } else {\n this.latencyTimestamps.set(key, value);\n // new offer/answer so reset the remote SDP timestamp\n if (key === 'client.media-engine.local-sdp-generated') {\n this.latencyTimestamps.delete('client.media-engine.remote-sdp-received');\n }\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(\n a: MetricEventNames,\n b: MetricEventNames,\n clampValues?: {minimum?: number; maximum?: number}\n ) {\n const start = this.latencyTimestamps.get(a);\n const end = this.latencyTimestamps.get(b);\n\n if (typeof start !== 'number' || typeof end !== 'number') {\n return undefined;\n }\n\n const diff = end - start;\n\n const {minimum = 0, maximum = this.MAX_INTEGER} = clampValues || {};\n\n return clamp(diff, minimum, maximum);\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 {maximum: 1200000}\n );\n }\n\n /**\n * Interstitial Time\n * @returns - latency\n */\n public getShowInterstitialTime() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.meeting.interstitial-window.showed',\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 typeof u2cLatency === 'number' ? 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 {maximum: 1200000}\n );\n }\n\n /**\n * Locus Join Request\n * @returns - latency\n */\n public getJoinReqResp() {\n return this.getDiffBetweenTimestamps(\n 'client.locus.join.request',\n 'client.locus.join.response',\n {maximum: 1200000}\n );\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 {maximum: 1200000}\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', {maximum: 1200000});\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('client.locus.join.response', 'client.lobby.exited');\n }\n\n /**\n * Page JMT\n * @returns - latency\n */\n public getPageJMT() {\n const latency = this.precomputedLatencies.get('internal.client.pageJMT');\n\n return typeof latency === 'number' ? clamp(latency, 0, this.MAX_INTEGER) : undefined;\n }\n\n /**\n * Download Time JMT\n * @returns - latency\n */\n public getDownloadTimeJMT() {\n const latency = this.precomputedLatencies.get('internal.download.time');\n\n return typeof latency === 'number' ? clamp(latency, 0, this.MAX_INTEGER) : 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 const clickToInterstitialLatency = this.precomputedLatencies.get(\n 'internal.click.to.interstitial'\n );\n\n if (typeof clickToInterstitialLatency === 'number') {\n return clamp(clickToInterstitialLatency, 0, this.MAX_INTEGER);\n }\n\n return undefined;\n }\n\n /**\n * Click To Interstitial With User Delay\n * @returns - latency\n */\n public getClickToInterstitialWithUserDelay() {\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 const clickToInterstitialWithUserDelayLatency = this.precomputedLatencies.get(\n 'internal.click.to.interstitial.with.user.delay'\n );\n\n if (typeof clickToInterstitialWithUserDelayLatency === 'number') {\n return clamp(clickToInterstitialWithUserDelayLatency, 0, this.MAX_INTEGER);\n }\n\n return 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 {maximum: 1200000}\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 lobbyTimeLatency = this.getStayLobbyTime();\n const lobbyTime = typeof lobbyTimeLatency === 'number' ? lobbyTimeLatency : 0;\n\n if (interstitialJoinClickTimestamp && connectedMedia) {\n const interstitialToMediaOKJmt = connectedMedia - interstitialJoinClickTimestamp - lobbyTime;\n\n return clamp(interstitialToMediaOKJmt, 0, this.MAX_INTEGER);\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 interstitialClickJoinToJoinLocusResponse = this.getDiffBetweenTimestamps(\n 'internal.client.interstitial-window.click.joinbutton',\n 'client.locus.join.response'\n );\n\n if (\n typeof clickToInterstitial === 'number' &&\n typeof interstitialClickJoinToJoinLocusResponse === 'number'\n ) {\n return clamp(\n clickToInterstitial + interstitialClickJoinToJoinLocusResponse,\n 0,\n this.MAX_INTEGER\n );\n }\n\n return undefined;\n }\n\n /**\n * Total JMT With User Delay\n * @returns - latency\n */\n public getTotalJMTWithUserDelay() {\n const clickToInterstitialWithUserDelay = this.getClickToInterstitialWithUserDelay();\n const interstitialShowedToJoinLocusResponse = this.getDiffBetweenTimestamps(\n 'internal.client.meeting.interstitial-window.showed',\n 'client.locus.join.response'\n );\n\n if (\n typeof clickToInterstitialWithUserDelay === 'number' &&\n typeof interstitialShowedToJoinLocusResponse === 'number'\n ) {\n return clamp(\n clickToInterstitialWithUserDelay + interstitialShowedToJoinLocusResponse,\n 0,\n this.MAX_INTEGER\n );\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 clamp(joinReqResp + ICESetupTime, 0, this.MAX_INTEGER);\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 lobbyTimeLatency = this.getStayLobbyTime();\n const lobbyTime = typeof lobbyTimeLatency === 'number' ? lobbyTimeLatency : 0;\n\n if (clickToInterstitial && interstitialToJoinOk && joinConfJMT) {\n const totalMediaJMT = clamp(\n clickToInterstitial + interstitialToJoinOk + joinConfJMT,\n 0,\n Infinity\n );\n if (this.getMeeting()?.allowMediaInLobby) {\n return clamp(totalMediaJMT, 0, this.MAX_INTEGER);\n }\n\n return clamp(totalMediaJMT - lobbyTime, 0, this.MAX_INTEGER);\n }\n\n return undefined;\n }\n\n /**\n * Total Media JMT With User Delay\n * @returns - latency\n */\n public getTotalMediaJMTWithUserDelay() {\n const clickToInterstitialWithUserDelay = this.getClickToInterstitialWithUserDelay();\n const interstitialToJoinOk = this.getInterstitialToJoinOK();\n const joinConfJMT = this.getJoinConfJMT();\n\n if (clickToInterstitialWithUserDelay && interstitialToJoinOk && joinConfJMT) {\n return clamp(\n clickToInterstitialWithUserDelay + interstitialToJoinOk + joinConfJMT,\n 0,\n this.MAX_INTEGER\n );\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 (typeof interstitialToJoinOk === 'number' && typeof joinConfJMT === 'number') {\n return clamp(interstitialToJoinOk - joinConfJMT, 0, this.MAX_INTEGER);\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 typeof reachablityClusterReqResp === 'number'\n ? clamp(Math.floor(reachablityClusterReqResp), 0, this.MAX_INTEGER)\n : 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 * Time from share initiation to share stop (ms).\n */\n public getShareDuration() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.share.initiated',\n 'internal.client.share.stopped'\n );\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 typeof exchangeCITokenJMT === 'number'\n ? clamp(Math.floor(exchangeCITokenJMT), 0, this.MAX_INTEGER)\n : 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 typeof refreshCaptchaReqResp === 'number'\n ? clamp(Math.floor(refreshCaptchaReqResp), 0, this.MAX_INTEGER)\n : 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 typeof downloadIntelligenceModelsReqResp === 'number'\n ? clamp(Math.floor(downloadIntelligenceModelsReqResp), 0, this.MAX_INTEGER)\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 ? clamp(Math.floor(otherAppApiJMT), 0, this.MAX_INTEGER) : undefined;\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_webexCore","require","_lodash","_callSuper","t","o","e","_getPrototypeOf2","default","_possibleConstructorReturn2","_isNativeReflectConstruct","_Reflect$construct","constructor","apply","Boolean","prototype","valueOf","call","CallDiagnosticLatencies","exports","_WebexPlugin","_this","_classCallCheck2","_len","arguments","length","args","Array","_key","concat","_defineProperty2","latencyTimestamps","_map","precomputedLatencies","_inherits2","_createClass2","key","value","clearTimestamps","clear","setMeetingId","meetingId","getMeeting","webex","meetings","getBasicMeetingInformation","undefined","saveTimestamp","_ref","_ref$value","Date","getTime","_ref$options","options","saveFirstTimestampOnly","set","delete","saveLatency","accumulate","existingValue","get","measureLatency","callback","_this2","start","performance","now","finally","has","getDiffBetweenTimestamps","a","b","clampValues","end","diff","_ref2","_ref2$minimum","minimum","_ref2$maximum","maximum","MAX_INTEGER","clamp","getMeetingInfoReqResp","getShowInterstitialTime","getU2CTime","u2cLatency","Math","floor","getRegisterWDMDeviceJMT","getCallInitJoinReq","getJoinReqResp","getTurnDiscoveryTime","getLocalSDPGenRemoteSDPRecv","getICESetupTime","getAudioICESetupTime","getVideoICESetupTime","getShareICESetupTime","getStayLobbyTime","getStayLobbyTimeCappedBy","endTimestampKey","lobbyStartTimestamp","lobbyEndTimestamp","maximumEndTimestamp","endTimestamp","min","getPageJMT","latency","getDownloadTimeJMT","getClickToInterstitial","clickToInterstitialLatency","getClickToInterstitialWithUserDelay","clickToInterstitialWithUserDelayLatency","getInterstitialToJoinOK","getCallInitMediaEngineReady","getInterstitialToMediaOKJMT","interstitialClickJoinToIceEnd","stayLobbyTimeCappedByIceEnd","getTotalJMT","clickToInterstitial","interstitialClickJoinToJoinLocusResponse","getTotalJMTWithUserDelay","clickToInterstitialWithUserDelay","interstitialShowedToJoinLocusResponse","getJoinConfJMT","joinReqResp","ICESetupTime","getTotalMediaJMT","interstitialClickJoinToMediaEngineReady","stayLobbyTimeCappedByMediaEngineReady","getTotalMediaJMTWithUserDelay","interstitialShowedToMediaEngineReady","getClientJMT","interstitialToJoinOk","joinConfJMT","getAudioJoinRespRxStart","getVideoJoinRespRxStart","getReachabilityClustersReqResp","reachablityClusterReqResp","getAudioJoinRespTxStart","getVideoJoinRespTxStart","getShareDuration","getExchangeCITokenJMT","exchangeCITokenJMT","getRefreshCaptchaReqResp","refreshCaptchaReqResp","getDownloadIntelligenceModelsReqResp","downloadIntelligenceModelsReqResp","getOtherAppApiReqResp","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';\nimport {clamp} from 'lodash';\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 private MAX_INTEGER = 2147483647;\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.getBasicMeetingInformation(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 key === 'client.media-engine.remote-sdp-received'\n ) {\n this.saveFirstTimestampOnly(key, value);\n } else {\n this.latencyTimestamps.set(key, value);\n // new offer/answer so reset the remote SDP timestamp\n if (key === 'client.media-engine.local-sdp-generated') {\n this.latencyTimestamps.delete('client.media-engine.remote-sdp-received');\n }\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(\n a: MetricEventNames,\n b: MetricEventNames,\n clampValues?: {minimum?: number; maximum?: number}\n ) {\n const start = this.latencyTimestamps.get(a);\n const end = this.latencyTimestamps.get(b);\n\n if (typeof start !== 'number' || typeof end !== 'number') {\n return undefined;\n }\n\n const diff = end - start;\n\n const {minimum = 0, maximum = this.MAX_INTEGER} = clampValues || {};\n\n return clamp(diff, minimum, maximum);\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 {maximum: 1200000}\n );\n }\n\n /**\n * Interstitial Time\n * @returns - latency\n */\n public getShowInterstitialTime() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.meeting.interstitial-window.showed',\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 typeof u2cLatency === 'number' ? 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 {maximum: 1200000}\n );\n }\n\n /**\n * Locus Join Request\n * @returns - latency\n */\n public getJoinReqResp() {\n return this.getDiffBetweenTimestamps(\n 'client.locus.join.request',\n 'client.locus.join.response',\n {maximum: 1200000}\n );\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 {maximum: 1200000}\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', {maximum: 1200000});\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('client.locus.join.response', 'client.lobby.exited');\n }\n\n /**\n * Stay lobby time capped by a certain timestamp.\n * This is to handle the case where the target end timestamp could happen before the lobby is exited,\n * for example media-engine.ready or client.ice.end\n * @param endTimestampKey name of the target end event\n * @returns - latency\n */\n public getStayLobbyTimeCappedBy(endTimestampKey: MetricEventNames) {\n const lobbyStartTimestamp = this.latencyTimestamps.get('client.locus.join.response'); // must exist\n const lobbyEndTimestamp = this.latencyTimestamps.get('client.lobby.exited'); // might not exist\n const maximumEndTimestamp = this.latencyTimestamps.get(endTimestampKey); // must exist\n\n if (typeof lobbyStartTimestamp !== 'number' || typeof maximumEndTimestamp !== 'number') {\n return undefined;\n }\n\n const endTimestamp =\n typeof lobbyEndTimestamp === 'number'\n ? Math.min(lobbyEndTimestamp, maximumEndTimestamp)\n : maximumEndTimestamp;\n\n return clamp(endTimestamp - lobbyStartTimestamp, 0, this.MAX_INTEGER);\n }\n\n /**\n * Page JMT\n * @returns - latency\n */\n public getPageJMT() {\n const latency = this.precomputedLatencies.get('internal.client.pageJMT');\n\n return typeof latency === 'number' ? clamp(latency, 0, this.MAX_INTEGER) : undefined;\n }\n\n /**\n * Download Time JMT\n * @returns - latency\n */\n public getDownloadTimeJMT() {\n const latency = this.precomputedLatencies.get('internal.download.time');\n\n return typeof latency === 'number' ? clamp(latency, 0, this.MAX_INTEGER) : 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 const clickToInterstitialLatency = this.precomputedLatencies.get(\n 'internal.click.to.interstitial'\n );\n\n if (typeof clickToInterstitialLatency === 'number') {\n return clamp(clickToInterstitialLatency, 0, this.MAX_INTEGER);\n }\n\n return undefined;\n }\n\n /**\n * Click To Interstitial With User Delay\n * @returns - latency\n */\n public getClickToInterstitialWithUserDelay() {\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 const clickToInterstitialWithUserDelayLatency = this.precomputedLatencies.get(\n 'internal.click.to.interstitial.with.user.delay'\n );\n\n if (typeof clickToInterstitialWithUserDelayLatency === 'number') {\n return clamp(clickToInterstitialWithUserDelayLatency, 0, this.MAX_INTEGER);\n }\n\n return 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.getInterstitialToMediaOKJMT();\n }\n\n /**\n * Interstitial To Media Ok\n * @returns - latency\n */\n public getInterstitialToMediaOKJMT() {\n const interstitialClickJoinToIceEnd = this.getDiffBetweenTimestamps(\n 'internal.client.interstitial-window.click.joinbutton',\n 'client.ice.end'\n );\n const stayLobbyTimeCappedByIceEnd = this.getStayLobbyTimeCappedBy('client.ice.end');\n\n if (\n typeof interstitialClickJoinToIceEnd === 'number' &&\n typeof stayLobbyTimeCappedByIceEnd === 'number'\n ) {\n return clamp(\n interstitialClickJoinToIceEnd - stayLobbyTimeCappedByIceEnd,\n 0,\n this.MAX_INTEGER\n );\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 interstitialClickJoinToJoinLocusResponse = this.getDiffBetweenTimestamps(\n 'internal.client.interstitial-window.click.joinbutton',\n 'client.locus.join.response'\n );\n\n if (\n typeof clickToInterstitial === 'number' &&\n typeof interstitialClickJoinToJoinLocusResponse === 'number'\n ) {\n return clamp(\n clickToInterstitial + interstitialClickJoinToJoinLocusResponse,\n 0,\n this.MAX_INTEGER\n );\n }\n\n return undefined;\n }\n\n /**\n * Total JMT With User Delay\n * @returns - latency\n */\n public getTotalJMTWithUserDelay() {\n const clickToInterstitialWithUserDelay = this.getClickToInterstitialWithUserDelay();\n const interstitialShowedToJoinLocusResponse = this.getDiffBetweenTimestamps(\n 'internal.client.meeting.interstitial-window.showed',\n 'client.locus.join.response'\n );\n\n if (\n typeof clickToInterstitialWithUserDelay === 'number' &&\n typeof interstitialShowedToJoinLocusResponse === 'number'\n ) {\n return clamp(\n clickToInterstitialWithUserDelay + interstitialShowedToJoinLocusResponse,\n 0,\n this.MAX_INTEGER\n );\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 clamp(joinReqResp + ICESetupTime, 0, this.MAX_INTEGER);\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 interstitialClickJoinToMediaEngineReady = this.getDiffBetweenTimestamps(\n 'internal.client.interstitial-window.click.joinbutton',\n 'client.media-engine.ready'\n );\n const stayLobbyTimeCappedByMediaEngineReady = this.getStayLobbyTimeCappedBy(\n 'client.media-engine.ready'\n );\n\n if (\n typeof clickToInterstitial === 'number' &&\n typeof interstitialClickJoinToMediaEngineReady === 'number' &&\n typeof stayLobbyTimeCappedByMediaEngineReady === 'number'\n ) {\n return clamp(\n clickToInterstitial +\n interstitialClickJoinToMediaEngineReady -\n stayLobbyTimeCappedByMediaEngineReady,\n 0,\n this.MAX_INTEGER\n );\n }\n\n return undefined;\n }\n\n /**\n * Total Media JMT With User Delay\n * @returns - latency\n */\n public getTotalMediaJMTWithUserDelay() {\n const clickToInterstitialWithUserDelay = this.getClickToInterstitialWithUserDelay();\n const interstitialShowedToMediaEngineReady = this.getDiffBetweenTimestamps(\n 'internal.client.meeting.interstitial-window.showed',\n 'client.media-engine.ready'\n );\n\n if (\n typeof clickToInterstitialWithUserDelay === 'number' &&\n typeof interstitialShowedToMediaEngineReady === 'number'\n ) {\n return clamp(\n clickToInterstitialWithUserDelay + interstitialShowedToMediaEngineReady,\n 0,\n this.MAX_INTEGER\n );\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 (typeof interstitialToJoinOk === 'number' && typeof joinConfJMT === 'number') {\n return clamp(interstitialToJoinOk - joinConfJMT, 0, this.MAX_INTEGER);\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 typeof reachablityClusterReqResp === 'number'\n ? clamp(Math.floor(reachablityClusterReqResp), 0, this.MAX_INTEGER)\n : 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 * Time from share initiation to share stop (ms).\n */\n public getShareDuration() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.share.initiated',\n 'internal.client.share.stopped'\n );\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 typeof exchangeCITokenJMT === 'number'\n ? clamp(Math.floor(exchangeCITokenJMT), 0, this.MAX_INTEGER)\n : 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 typeof refreshCaptchaReqResp === 'number'\n ? clamp(Math.floor(refreshCaptchaReqResp), 0, this.MAX_INTEGER)\n : 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 typeof downloadIntelligenceModelsReqResp === 'number'\n ? clamp(Math.floor(downloadIntelligenceModelsReqResp), 0, this.MAX_INTEGER)\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 ? clamp(Math.floor(otherAppApiJMT), 0, this.MAX_INTEGER) : undefined;\n }\n}\n"],"mappings":"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","ignoreList":[]}
package/dist/metrics.js CHANGED
@@ -147,7 +147,7 @@ var Metrics = _webexCore.WebexPlugin.extend({
147
147
  }
148
148
  });
149
149
  },
150
- version: "3.12.0-next.5"
150
+ version: "3.12.0-next.7"
151
151
  });
152
152
  var _default = exports.default = Metrics;
153
153
  //# sourceMappingURL=metrics.js.map
@@ -149,6 +149,14 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
149
149
  * @returns - latency
150
150
  */
151
151
  getStayLobbyTime(): number;
152
+ /**
153
+ * Stay lobby time capped by a certain timestamp.
154
+ * This is to handle the case where the target end timestamp could happen before the lobby is exited,
155
+ * for example media-engine.ready or client.ice.end
156
+ * @param endTimestampKey name of the target end event
157
+ * @returns - latency
158
+ */
159
+ getStayLobbyTimeCappedBy(endTimestampKey: MetricEventNames): number;
152
160
  /**
153
161
  * Page JMT
154
162
  * @returns - latency
package/package.json CHANGED
@@ -40,7 +40,7 @@
40
40
  "@webex/common-timers": "3.11.0-next.1",
41
41
  "@webex/test-helper-chai": "3.11.0-next.1",
42
42
  "@webex/test-helper-mock-webex": "3.11.0-next.1",
43
- "@webex/webex-core": "3.12.0-next.5",
43
+ "@webex/webex-core": "3.12.0-next.7",
44
44
  "ip-anonymize": "^0.1.0",
45
45
  "lodash": "^4.17.21",
46
46
  "uuid": "^3.3.2"
@@ -53,5 +53,5 @@
53
53
  "test:style": "eslint ./src/**/*.*",
54
54
  "test:unit": "webex-legacy-tools test --unit --runner mocha"
55
55
  },
56
- "version": "3.12.0-next.5"
56
+ "version": "3.12.0-next.7"
57
57
  }
@@ -306,6 +306,30 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
306
306
  return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.lobby.exited');
307
307
  }
308
308
 
309
+ /**
310
+ * Stay lobby time capped by a certain timestamp.
311
+ * This is to handle the case where the target end timestamp could happen before the lobby is exited,
312
+ * for example media-engine.ready or client.ice.end
313
+ * @param endTimestampKey name of the target end event
314
+ * @returns - latency
315
+ */
316
+ public getStayLobbyTimeCappedBy(endTimestampKey: MetricEventNames) {
317
+ const lobbyStartTimestamp = this.latencyTimestamps.get('client.locus.join.response'); // must exist
318
+ const lobbyEndTimestamp = this.latencyTimestamps.get('client.lobby.exited'); // might not exist
319
+ const maximumEndTimestamp = this.latencyTimestamps.get(endTimestampKey); // must exist
320
+
321
+ if (typeof lobbyStartTimestamp !== 'number' || typeof maximumEndTimestamp !== 'number') {
322
+ return undefined;
323
+ }
324
+
325
+ const endTimestamp =
326
+ typeof lobbyEndTimestamp === 'number'
327
+ ? Math.min(lobbyEndTimestamp, maximumEndTimestamp)
328
+ : maximumEndTimestamp;
329
+
330
+ return clamp(endTimestamp - lobbyStartTimestamp, 0, this.MAX_INTEGER);
331
+ }
332
+
309
333
  /**
310
334
  * Page JMT
311
335
  * @returns - latency
@@ -390,11 +414,7 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
390
414
  * @returns - latency
391
415
  */
392
416
  public getCallInitMediaEngineReady() {
393
- return this.getDiffBetweenTimestamps(
394
- 'internal.client.interstitial-window.click.joinbutton',
395
- 'client.media-engine.ready',
396
- {maximum: 1200000}
397
- );
417
+ return this.getInterstitialToMediaOKJMT();
398
418
  }
399
419
 
400
420
  /**
@@ -402,20 +422,21 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
402
422
  * @returns - latency
403
423
  */
404
424
  public getInterstitialToMediaOKJMT() {
405
- const interstitialJoinClickTimestamp = this.latencyTimestamps.get(
406
- 'internal.client.interstitial-window.click.joinbutton'
425
+ const interstitialClickJoinToIceEnd = this.getDiffBetweenTimestamps(
426
+ 'internal.client.interstitial-window.click.joinbutton',
427
+ 'client.ice.end'
407
428
  );
429
+ const stayLobbyTimeCappedByIceEnd = this.getStayLobbyTimeCappedBy('client.ice.end');
408
430
 
409
- // get the first timestamp
410
- const connectedMedia = this.latencyTimestamps.get('client.ice.end');
411
-
412
- const lobbyTimeLatency = this.getStayLobbyTime();
413
- const lobbyTime = typeof lobbyTimeLatency === 'number' ? lobbyTimeLatency : 0;
414
-
415
- if (interstitialJoinClickTimestamp && connectedMedia) {
416
- const interstitialToMediaOKJmt = connectedMedia - interstitialJoinClickTimestamp - lobbyTime;
417
-
418
- return clamp(interstitialToMediaOKJmt, 0, this.MAX_INTEGER);
431
+ if (
432
+ typeof interstitialClickJoinToIceEnd === 'number' &&
433
+ typeof stayLobbyTimeCappedByIceEnd === 'number'
434
+ ) {
435
+ return clamp(
436
+ interstitialClickJoinToIceEnd - stayLobbyTimeCappedByIceEnd,
437
+ 0,
438
+ this.MAX_INTEGER
439
+ );
419
440
  }
420
441
 
421
442
  return undefined;
@@ -492,22 +513,26 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
492
513
  */
493
514
  public getTotalMediaJMT() {
494
515
  const clickToInterstitial = this.getClickToInterstitial();
495
- const interstitialToJoinOk = this.getInterstitialToJoinOK();
496
- const joinConfJMT = this.getJoinConfJMT();
497
- const lobbyTimeLatency = this.getStayLobbyTime();
498
- const lobbyTime = typeof lobbyTimeLatency === 'number' ? lobbyTimeLatency : 0;
516
+ const interstitialClickJoinToMediaEngineReady = this.getDiffBetweenTimestamps(
517
+ 'internal.client.interstitial-window.click.joinbutton',
518
+ 'client.media-engine.ready'
519
+ );
520
+ const stayLobbyTimeCappedByMediaEngineReady = this.getStayLobbyTimeCappedBy(
521
+ 'client.media-engine.ready'
522
+ );
499
523
 
500
- if (clickToInterstitial && interstitialToJoinOk && joinConfJMT) {
501
- const totalMediaJMT = clamp(
502
- clickToInterstitial + interstitialToJoinOk + joinConfJMT,
524
+ if (
525
+ typeof clickToInterstitial === 'number' &&
526
+ typeof interstitialClickJoinToMediaEngineReady === 'number' &&
527
+ typeof stayLobbyTimeCappedByMediaEngineReady === 'number'
528
+ ) {
529
+ return clamp(
530
+ clickToInterstitial +
531
+ interstitialClickJoinToMediaEngineReady -
532
+ stayLobbyTimeCappedByMediaEngineReady,
503
533
  0,
504
- Infinity
534
+ this.MAX_INTEGER
505
535
  );
506
- if (this.getMeeting()?.allowMediaInLobby) {
507
- return clamp(totalMediaJMT, 0, this.MAX_INTEGER);
508
- }
509
-
510
- return clamp(totalMediaJMT - lobbyTime, 0, this.MAX_INTEGER);
511
536
  }
512
537
 
513
538
  return undefined;
@@ -519,12 +544,17 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
519
544
  */
520
545
  public getTotalMediaJMTWithUserDelay() {
521
546
  const clickToInterstitialWithUserDelay = this.getClickToInterstitialWithUserDelay();
522
- const interstitialToJoinOk = this.getInterstitialToJoinOK();
523
- const joinConfJMT = this.getJoinConfJMT();
547
+ const interstitialShowedToMediaEngineReady = this.getDiffBetweenTimestamps(
548
+ 'internal.client.meeting.interstitial-window.showed',
549
+ 'client.media-engine.ready'
550
+ );
524
551
 
525
- if (clickToInterstitialWithUserDelay && interstitialToJoinOk && joinConfJMT) {
552
+ if (
553
+ typeof clickToInterstitialWithUserDelay === 'number' &&
554
+ typeof interstitialShowedToMediaEngineReady === 'number'
555
+ ) {
526
556
  return clamp(
527
- clickToInterstitialWithUserDelay + interstitialToJoinOk + joinConfJMT,
557
+ clickToInterstitialWithUserDelay + interstitialShowedToMediaEngineReady,
528
558
  0,
529
559
  this.MAX_INTEGER
530
560
  );
@@ -346,6 +346,9 @@ describe('plugin-metrics', () => {
346
346
  webex.internal.newMetrics.callDiagnosticLatencies.getStayLobbyTime = sinon
347
347
  .stub()
348
348
  .returns(1);
349
+ webex.internal.newMetrics.callDiagnosticLatencies.getStayLobbyTimeCappedBy = sinon
350
+ .stub()
351
+ .returns(1);
349
352
  webex.internal.newMetrics.callDiagnosticLatencies.getTotalMediaJMTWithUserDelay = sinon
350
353
  .stub()
351
354
  .returns(43);
@@ -366,9 +369,9 @@ describe('plugin-metrics', () => {
366
369
  assert.deepEqual(webex.request.getCalls()[0].args[0].body.metrics[0].eventPayload.event, {
367
370
  name: 'client.media-engine.ready',
368
371
  joinTimes: {
369
- totalMediaJMT: 61,
372
+ totalMediaJMT: 44,
370
373
  interstitialToMediaOKJMT: 22,
371
- callInitMediaEngineReady: 10,
374
+ callInitMediaEngineReady: 22,
372
375
  totalMediaJMTWithUserDelay: 43,
373
376
  totalJMTWithUserDelay: 64,
374
377
  },
@@ -519,6 +519,50 @@ describe('internal-plugin-metrics', () => {
519
519
  assert.deepEqual(cdl.getStayLobbyTime(), 10);
520
520
  });
521
521
 
522
+ describe('getStayLobbyTimeCappedBy', () => {
523
+ it('returns undefined when lobbyStartTimestamp is missing', () => {
524
+ cdl.saveTimestamp({key: 'client.media-engine.ready', value: 100});
525
+ assert.deepEqual(cdl.getStayLobbyTimeCappedBy('client.media-engine.ready'), undefined);
526
+ });
527
+
528
+ it('returns undefined when endTimestampKey is missing', () => {
529
+ cdl.saveTimestamp({key: 'client.locus.join.response', value: 10});
530
+ assert.deepEqual(cdl.getStayLobbyTimeCappedBy('client.media-engine.ready'), undefined);
531
+ });
532
+
533
+ it('uses maximumEndTimestamp when lobby end does not exist', () => {
534
+ cdl.saveTimestamp({key: 'client.locus.join.response', value: 10});
535
+ cdl.saveTimestamp({key: 'client.media-engine.ready', value: 50});
536
+ assert.deepEqual(cdl.getStayLobbyTimeCappedBy('client.media-engine.ready'), 40);
537
+ });
538
+
539
+ it('uses lobby end when it is before maximumEndTimestamp', () => {
540
+ cdl.saveTimestamp({key: 'client.locus.join.response', value: 10});
541
+ cdl.saveTimestamp({key: 'client.lobby.exited', value: 30});
542
+ cdl.saveTimestamp({key: 'client.media-engine.ready', value: 50});
543
+ assert.deepEqual(cdl.getStayLobbyTimeCappedBy('client.media-engine.ready'), 20);
544
+ });
545
+
546
+ it('uses maximumEndTimestamp when lobby end is after it', () => {
547
+ cdl.saveTimestamp({key: 'client.locus.join.response', value: 10});
548
+ cdl.saveTimestamp({key: 'client.lobby.exited', value: 60});
549
+ cdl.saveTimestamp({key: 'client.media-engine.ready', value: 50});
550
+ assert.deepEqual(cdl.getStayLobbyTimeCappedBy('client.media-engine.ready'), 40);
551
+ });
552
+
553
+ it('clamps to 0 when result would be negative', () => {
554
+ cdl.saveTimestamp({key: 'client.locus.join.response', value: 100});
555
+ cdl.saveTimestamp({key: 'client.media-engine.ready', value: 50});
556
+ assert.deepEqual(cdl.getStayLobbyTimeCappedBy('client.media-engine.ready'), 0);
557
+ });
558
+
559
+ it('clamps to MAX_INTEGER when result is very large', () => {
560
+ cdl.saveTimestamp({key: 'client.locus.join.response', value: 0});
561
+ cdl.saveTimestamp({key: 'client.media-engine.ready', value: 2147483648});
562
+ assert.deepEqual(cdl.getStayLobbyTimeCappedBy('client.media-engine.ready'), 2147483647);
563
+ });
564
+ });
565
+
522
566
  it('calculates getPageJMT correctly', () => {
523
567
  cdl.saveLatency('internal.client.pageJMT', 10);
524
568
  assert.deepEqual(cdl.getPageJMT(), 10);
@@ -624,15 +668,8 @@ describe('internal-plugin-metrics', () => {
624
668
  });
625
669
 
626
670
  it('calculates getCallInitMediaEngineReady correctly', () => {
627
- cdl.saveTimestamp({
628
- key: 'internal.client.interstitial-window.click.joinbutton',
629
- value: 10,
630
- });
631
- cdl.saveTimestamp({
632
- key: 'client.media-engine.ready',
633
- value: 20,
634
- });
635
- assert.deepEqual(cdl.getCallInitMediaEngineReady(), 10);
671
+ sinon.stub(cdl, 'getInterstitialToMediaOKJMT').returns(42);
672
+ assert.deepEqual(cdl.getCallInitMediaEngineReady(), 42);
636
673
  });
637
674
 
638
675
  it('calculates getTotalJMT correctly', () => {
@@ -808,215 +845,97 @@ describe('internal-plugin-metrics', () => {
808
845
  assert.deepEqual(cdl.getTotalJMTWithUserDelay(), 2147483647);
809
846
  });
810
847
 
811
- it('calculates getTotalMediaJMT correctly', () => {
812
- cdl.saveTimestamp({
813
- key: 'internal.client.meeting.click.joinbutton',
814
- value: 5,
815
- });
816
- cdl.saveTimestamp({
817
- key: 'internal.client.meeting.interstitial-window.showed',
818
- value: 8,
819
- });
820
- cdl.saveTimestamp({
821
- key: 'internal.client.interstitial-window.click.joinbutton',
822
- value: 10,
823
- });
824
- cdl.saveTimestamp({
825
- key: 'client.locus.join.request',
826
- value: 12,
827
- });
828
- cdl.saveTimestamp({
829
- key: 'client.locus.join.response',
830
- value: 20,
831
- });
832
- cdl.saveTimestamp({
833
- key: 'client.lobby.exited',
834
- value: 24,
835
- });
836
- cdl.saveTimestamp({
837
- key: 'client.ice.start',
838
- value: 30,
839
- });
840
- cdl.saveTimestamp({
841
- key: 'client.ice.end',
842
- value: 40,
843
- });
844
- assert.deepEqual(cdl.getTotalMediaJMT(), 27);
848
+ it('calculates getTotalMediaJMT correctly with lobby exiting before media-engine.ready', () => {
849
+ cdl.saveTimestamp({key: 'internal.client.meeting.click.joinbutton', value: 5});
850
+ cdl.saveTimestamp({key: 'internal.client.meeting.interstitial-window.showed', value: 8});
851
+ // clickToInterstitial = 8 - 5 = 3
852
+ cdl.saveTimestamp({key: 'internal.client.interstitial-window.click.joinbutton', value: 10});
853
+ cdl.saveTimestamp({key: 'client.media-engine.ready', value: 50});
854
+ // interstitialClickJoinToMediaEngineReady = 50 - 10 = 40
855
+ cdl.saveTimestamp({key: 'client.locus.join.response', value: 20});
856
+ cdl.saveTimestamp({key: 'client.lobby.exited', value: 30});
857
+ // stayLobbyTimeCappedByMediaEngineReady = min(30, 50) - 20 = 10
858
+ // total = 3 + 40 - 10 = 33
859
+ assert.deepEqual(cdl.getTotalMediaJMT(), 33);
860
+ });
861
+
862
+ it('calculates getTotalMediaJMT correctly without lobby', () => {
863
+ cdl.saveTimestamp({key: 'internal.client.meeting.click.joinbutton', value: 5});
864
+ cdl.saveTimestamp({key: 'internal.client.meeting.interstitial-window.showed', value: 8});
865
+ // clickToInterstitial = 3
866
+ cdl.saveTimestamp({key: 'internal.client.interstitial-window.click.joinbutton', value: 10});
867
+ cdl.saveTimestamp({key: 'client.media-engine.ready', value: 50});
868
+ // interstitialClickJoinToMediaEngineReady = 40
869
+ cdl.saveTimestamp({key: 'client.locus.join.response', value: 20});
870
+ // no client.lobby.exited
871
+ // stayLobbyTimeCappedByMediaEngineReady = 50 - 20 = 30
872
+ // total = 3 + 40 - 30 = 13
873
+ assert.deepEqual(cdl.getTotalMediaJMT(), 13);
874
+ });
875
+
876
+ it('calculates getTotalMediaJMT correctly with lobby exiting after media-engine.ready', () => {
877
+ cdl.saveTimestamp({key: 'internal.client.meeting.click.joinbutton', value: 5});
878
+ cdl.saveTimestamp({key: 'internal.client.meeting.interstitial-window.showed', value: 8});
879
+ // clickToInterstitial = 3
880
+ cdl.saveTimestamp({key: 'internal.client.interstitial-window.click.joinbutton', value: 10});
881
+ cdl.saveTimestamp({key: 'client.media-engine.ready', value: 50});
882
+ // interstitialClickJoinToMediaEngineReady = 40
883
+ cdl.saveTimestamp({key: 'client.locus.join.response', value: 20});
884
+ cdl.saveTimestamp({key: 'client.lobby.exited', value: 60});
885
+ // stayLobbyTimeCappedByMediaEngineReady = min(60, 50) - 20 = 30
886
+ // total = 3 + 40 - 30 = 13
887
+ assert.deepEqual(cdl.getTotalMediaJMT(), 13);
845
888
  });
846
889
 
847
890
  it('calculates getTotalMediaJMT correctly when it is greater than MAX_INTEGER', () => {
848
- cdl.saveTimestamp({
849
- key: 'internal.client.meeting.click.joinbutton',
850
- value: 5,
851
- });
852
- cdl.saveTimestamp({
853
- key: 'internal.client.meeting.interstitial-window.showed',
854
- value: 8,
855
- });
856
- cdl.saveTimestamp({
857
- key: 'internal.client.interstitial-window.click.joinbutton',
858
- value: 10,
859
- });
860
- cdl.saveTimestamp({
861
- key: 'client.locus.join.request',
862
- value: 12,
863
- });
864
- cdl.saveTimestamp({
865
- key: 'client.locus.join.response',
866
- value: 2147483700,
867
- });
868
- cdl.saveTimestamp({
869
- key: 'client.lobby.exited',
870
- value: 2147483800,
871
- });
872
- cdl.saveTimestamp({
873
- key: 'client.ice.start',
874
- value: 30,
875
- });
876
- cdl.saveTimestamp({
877
- key: 'client.ice.end',
878
- value: 100,
879
- });
891
+ cdl.saveTimestamp({key: 'internal.client.meeting.click.joinbutton', value: 5});
892
+ cdl.saveTimestamp({key: 'internal.client.meeting.interstitial-window.showed', value: 8});
893
+ cdl.saveTimestamp({key: 'internal.client.interstitial-window.click.joinbutton', value: 10});
894
+ cdl.saveTimestamp({key: 'client.media-engine.ready', value: 4294967400});
895
+ cdl.saveTimestamp({key: 'client.locus.join.response', value: 28});
896
+ cdl.saveTimestamp({key: 'client.lobby.exited', value: 30});
880
897
  assert.deepEqual(cdl.getTotalMediaJMT(), 2147483647);
881
898
  });
882
899
 
883
- it('calculates getTotalMediaJMT correctly with allowMediaInLobby true', () => {
884
- cdl.saveTimestamp({
885
- key: 'internal.client.meeting.click.joinbutton',
886
- value: 5,
887
- options: {meetingId: 'meeting-id'},
888
- });
889
- cdl.saveTimestamp({
890
- key: 'internal.client.meeting.interstitial-window.showed',
891
- value: 8,
892
- });
893
- cdl.saveTimestamp({
894
- key: 'internal.client.interstitial-window.click.joinbutton',
895
- value: 10,
896
- });
897
- cdl.saveTimestamp({
898
- key: 'client.locus.join.request',
899
- value: 12,
900
- });
901
- cdl.saveTimestamp({
902
- key: 'client.locus.join.response',
903
- value: 20,
904
- });
905
- cdl.saveTimestamp({
906
- key: 'client.lobby.exited',
907
- value: 24,
908
- });
909
- cdl.saveTimestamp({
910
- key: 'client.ice.start',
911
- value: 30,
912
- });
913
- cdl.saveTimestamp({
914
- key: 'client.ice.end',
915
- value: 40,
916
- });
917
- assert.deepEqual(cdl.getTotalMediaJMT(), 31);
918
- });
919
-
920
- it('calculates getTotalMediaJMT correctly with allowMediaInLobby true and it is greater than MAX_INTEGER', () => {
921
- cdl.saveTimestamp({
922
- key: 'internal.client.meeting.click.joinbutton',
923
- value: 5,
924
- options: {meetingId: 'meeting-id'},
925
- });
926
- cdl.saveTimestamp({
927
- key: 'internal.client.meeting.interstitial-window.showed',
928
- value: 100,
929
- });
930
- cdl.saveTimestamp({
931
- key: 'internal.client.interstitial-window.click.joinbutton',
932
- value: 1000,
933
- });
934
- cdl.saveTimestamp({
935
- key: 'client.locus.join.request',
936
- value: 2000,
937
- });
938
- cdl.saveTimestamp({
939
- key: 'client.locus.join.response',
940
- value: 2147483700,
941
- });
942
- cdl.saveTimestamp({
943
- key: 'client.lobby.exited',
944
- value: 2147483800,
945
- });
946
- cdl.saveTimestamp({
947
- key: 'client.ice.start',
948
- value: 2147483900,
949
- });
950
- cdl.saveTimestamp({
951
- key: 'client.ice.end',
952
- value: 4294967400,
953
- });
954
- assert.deepEqual(cdl.getTotalMediaJMT(), 2147483647);
900
+ it('returns undefined for getTotalMediaJMT when media-engine.ready is missing', () => {
901
+ cdl.saveTimestamp({key: 'internal.client.meeting.click.joinbutton', value: 5});
902
+ cdl.saveTimestamp({key: 'internal.client.meeting.interstitial-window.showed', value: 8});
903
+ cdl.saveTimestamp({key: 'internal.client.interstitial-window.click.joinbutton', value: 10});
904
+ cdl.saveTimestamp({key: 'client.locus.join.response', value: 20});
905
+ assert.deepEqual(cdl.getTotalMediaJMT(), undefined);
955
906
  });
956
907
 
957
908
  it('calculates getTotalMediaJMTWithUserDelay correctly', () => {
958
909
  cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 7);
959
- cdl.saveTimestamp({
960
- key: 'internal.client.interstitial-window.click.joinbutton',
961
- value: 10,
962
- });
963
- cdl.saveTimestamp({
964
- key: 'client.locus.join.request',
965
- value: 12,
966
- });
967
- cdl.saveTimestamp({
968
- key: 'client.locus.join.response',
969
- value: 20,
970
- });
971
- cdl.saveTimestamp({
972
- key: 'internal.host.meeting.participant.admitted',
973
- value: 24,
974
- });
975
- cdl.saveTimestamp({
976
- key: 'client.ice.start',
977
- value: 30,
978
- });
979
- cdl.saveTimestamp({
980
- key: 'client.ice.end',
981
- value: 40,
982
- });
983
- assert.deepEqual(cdl.getTotalMediaJMTWithUserDelay(), 35);
910
+ // clickToInterstitialWithUserDelay = 7
911
+ cdl.saveTimestamp({key: 'internal.client.meeting.interstitial-window.showed', value: 10});
912
+ cdl.saveTimestamp({key: 'client.media-engine.ready', value: 50});
913
+ // interstitialShowedToMediaEngineReady = 50 - 10 = 40
914
+ // total = 7 + 40 = 47
915
+ assert.deepEqual(cdl.getTotalMediaJMTWithUserDelay(), 47);
984
916
  });
985
917
 
986
918
  it('calculates getTotalMediaJMTWithUserDelay correctly for guest join', () => {
987
- cdl.saveTimestamp({
988
- key: 'internal.client.meeting.click.joinbutton',
989
- value: 5,
990
- });
991
- cdl.saveTimestamp({
992
- key: 'internal.client.meeting.interstitial-window.showed',
993
- value: 8,
994
- });
995
- cdl.saveTimestamp({
996
- key: 'internal.client.interstitial-window.click.joinbutton',
997
- value: 10,
998
- });
999
- cdl.saveTimestamp({
1000
- key: 'client.locus.join.request',
1001
- value: 12,
1002
- });
1003
- cdl.saveTimestamp({
1004
- key: 'client.locus.join.response',
1005
- value: 20,
1006
- });
1007
- cdl.saveTimestamp({
1008
- key: 'internal.host.meeting.participant.admitted',
1009
- value: 24,
1010
- });
1011
- cdl.saveTimestamp({
1012
- key: 'client.ice.start',
1013
- value: 30,
1014
- });
1015
- cdl.saveTimestamp({
1016
- key: 'client.ice.end',
1017
- value: 40,
1018
- });
1019
- assert.deepEqual(cdl.getTotalMediaJMTWithUserDelay(), 31);
919
+ cdl.saveTimestamp({key: 'internal.client.meeting.click.joinbutton', value: 5});
920
+ cdl.saveTimestamp({key: 'internal.client.meeting.interstitial-window.showed', value: 8});
921
+ // clickToInterstitialWithUserDelay = 8 - 5 = 3
922
+ cdl.saveTimestamp({key: 'client.media-engine.ready', value: 50});
923
+ // interstitialShowedToMediaEngineReady = 50 - 8 = 42
924
+ // total = 3 + 42 = 45
925
+ assert.deepEqual(cdl.getTotalMediaJMTWithUserDelay(), 45);
926
+ });
927
+
928
+ it('returns undefined for getTotalMediaJMTWithUserDelay when media-engine.ready is missing', () => {
929
+ cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 7);
930
+ cdl.saveTimestamp({key: 'internal.client.meeting.interstitial-window.showed', value: 10});
931
+ assert.deepEqual(cdl.getTotalMediaJMTWithUserDelay(), undefined);
932
+ });
933
+
934
+ it('calculates getTotalMediaJMTWithUserDelay correctly when it is greater than MAX_INTEGER', () => {
935
+ cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 2147483648);
936
+ cdl.saveTimestamp({key: 'internal.client.meeting.interstitial-window.showed', value: 10});
937
+ cdl.saveTimestamp({key: 'client.media-engine.ready', value: 50});
938
+ assert.deepEqual(cdl.getTotalMediaJMTWithUserDelay(), 2147483647);
1020
939
  });
1021
940
 
1022
941
  it('calculates getJoinConfJMT correctly', () => {
@@ -1164,7 +1083,7 @@ describe('internal-plugin-metrics', () => {
1164
1083
  });
1165
1084
  cdl.saveTimestamp({
1166
1085
  key: 'client.lobby.exited',
1167
- value: 12,
1086
+ value: 10,
1168
1087
  });
1169
1088
  cdl.saveTimestamp({
1170
1089
  key: 'client.ice.end',
@@ -1178,11 +1097,15 @@ describe('internal-plugin-metrics', () => {
1178
1097
  key: 'internal.client.interstitial-window.click.joinbutton',
1179
1098
  value: 4,
1180
1099
  });
1100
+ cdl.saveTimestamp({
1101
+ key: 'client.locus.join.response',
1102
+ value: 8,
1103
+ });
1181
1104
  cdl.saveTimestamp({
1182
1105
  key: 'client.ice.end',
1183
1106
  value: 14,
1184
1107
  });
1185
- assert.deepEqual(cdl.getInterstitialToMediaOKJMT(), 10);
1108
+ assert.deepEqual(cdl.getInterstitialToMediaOKJMT(), 4);
1186
1109
  });
1187
1110
 
1188
1111
  it('calculates getShareDuration correctly', () => {