@webex/internal-plugin-mercury 3.12.0-auth-prejoin-fetch.1 → 3.12.0-llmrefactor.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +13 -2
- package/dist/index.js.map +1 -1
- package/dist/mercury-plugin.js +125 -0
- package/dist/mercury-plugin.js.map +1 -0
- package/dist/mercury.js +241 -419
- package/dist/mercury.js.map +1 -1
- package/package.json +17 -17
- package/src/index.js +3 -2
- package/src/mercury-plugin.ts +79 -0
- package/src/mercury.js +198 -404
- package/test/unit/spec/mercury-events.js +2 -5
- package/test/unit/spec/mercury-plugin.js +280 -0
- package/test/unit/spec/mercury.js +233 -282
package/dist/mercury.js
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
var _Array$from = require("@babel/runtime-corejs2/core-js/array/from");
|
|
4
|
-
var _Symbol = require("@babel/runtime-corejs2/core-js/symbol");
|
|
5
|
-
var _Symbol$iterator = require("@babel/runtime-corejs2/core-js/symbol/iterator");
|
|
6
|
-
var _Array$isArray = require("@babel/runtime-corejs2/core-js/array/is-array");
|
|
7
3
|
var _Object$keys2 = require("@babel/runtime-corejs2/core-js/object/keys");
|
|
8
4
|
var _Object$getOwnPropertySymbols = require("@babel/runtime-corejs2/core-js/object/get-own-property-symbols");
|
|
9
5
|
var _Object$getOwnPropertyDescriptor2 = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptor");
|
|
@@ -15,7 +11,6 @@ _Object$defineProperty(exports, "__esModule", {
|
|
|
15
11
|
value: true
|
|
16
12
|
});
|
|
17
13
|
exports.default = void 0;
|
|
18
|
-
var _map = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/map"));
|
|
19
14
|
var _now = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/date/now"));
|
|
20
15
|
var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));
|
|
21
16
|
var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
|
|
@@ -23,7 +18,6 @@ var _keys = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/objec
|
|
|
23
18
|
var _assign = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/assign"));
|
|
24
19
|
var _deleteProperty = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/reflect/delete-property"));
|
|
25
20
|
var _getOwnPropertyDescriptor = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptor"));
|
|
26
|
-
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/toConsumableArray"));
|
|
27
21
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
|
|
28
22
|
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/slicedToArray"));
|
|
29
23
|
var _applyDecoratedDescriptor2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/applyDecoratedDescriptor"));
|
|
@@ -41,15 +35,11 @@ var _dec, _dec2, _obj;
|
|
|
41
35
|
*/
|
|
42
36
|
function ownKeys(e, r) { var t = _Object$keys2(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return _Object$getOwnPropertyDescriptor2(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
43
37
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor2(t, r)); }); } return e; }
|
|
44
|
-
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof _Symbol && r[_Symbol$iterator] || r["@@iterator"]; if (!t) { if (_Array$isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
45
|
-
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? _Array$from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
46
|
-
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
47
38
|
var normalReconnectReasons = ['idle', 'done (forced)', 'pong not received', 'pong mismatch'];
|
|
48
39
|
var MERCURY_CLOSE_4000_METRIC = 'JS_SDK_MERCURY_CLOSE_4000';
|
|
49
40
|
var Mercury = _webexCore.WebexPlugin.extend((_dec = (0, _common.deprecated)('Mercury#listen(): Use Mercury#connect() instead'), _dec2 = (0, _common.deprecated)('Mercury#stopListening(): Use Mercury#disconnect() instead'), _obj = {
|
|
50
41
|
namespace: 'Mercury',
|
|
51
42
|
lastError: undefined,
|
|
52
|
-
defaultSessionId: 'mercury-default-session',
|
|
53
43
|
session: {
|
|
54
44
|
connected: {
|
|
55
45
|
default: false,
|
|
@@ -63,35 +53,19 @@ var Mercury = _webexCore.WebexPlugin.extend((_dec = (0, _common.deprecated)('Mer
|
|
|
63
53
|
default: false,
|
|
64
54
|
type: 'boolean'
|
|
65
55
|
},
|
|
66
|
-
|
|
67
|
-
default: function _default() {
|
|
68
|
-
return new _map.default();
|
|
69
|
-
},
|
|
70
|
-
type: 'object'
|
|
71
|
-
},
|
|
72
|
-
sessionWebSocketUrls: {
|
|
73
|
-
default: function _default() {
|
|
74
|
-
return new _map.default();
|
|
75
|
-
},
|
|
76
|
-
type: 'object'
|
|
77
|
-
},
|
|
78
|
-
backoffCalls: {
|
|
79
|
-
default: function _default() {
|
|
80
|
-
return new _map.default();
|
|
81
|
-
},
|
|
82
|
-
type: 'object'
|
|
83
|
-
},
|
|
84
|
-
_shutdownSwitchoverBackoffCalls: {
|
|
85
|
-
default: function _default() {
|
|
86
|
-
return new _map.default();
|
|
87
|
-
},
|
|
88
|
-
type: 'object'
|
|
89
|
-
},
|
|
56
|
+
socket: 'object',
|
|
90
57
|
localClusterServiceUrls: 'object',
|
|
91
58
|
mercuryTimeOffset: {
|
|
92
59
|
default: undefined,
|
|
93
60
|
type: 'number'
|
|
94
|
-
}
|
|
61
|
+
},
|
|
62
|
+
backoffCall: 'object',
|
|
63
|
+
_connectPromise: 'object',
|
|
64
|
+
_shutdownSwitchoverBackoffCall: 'object',
|
|
65
|
+
_shutdownSwitchoverId: 'string',
|
|
66
|
+
// Store the resolved (pre-proxy) URL so reconnection uses a catalog-valid host
|
|
67
|
+
// instead of the potentially rewritten socket.url from an interceptor.
|
|
68
|
+
resolvedWebSocketUrl: 'string'
|
|
95
69
|
},
|
|
96
70
|
derived: {
|
|
97
71
|
listening: {
|
|
@@ -140,70 +114,60 @@ var Mercury = _webexCore.WebexPlugin.extend((_dec = (0, _common.deprecated)('Mer
|
|
|
140
114
|
/**
|
|
141
115
|
* Attach event listeners to a socket.
|
|
142
116
|
* @param {Socket} socket - The socket to attach listeners to
|
|
143
|
-
* @param {sessionId} sessionId - The socket related session ID
|
|
144
117
|
* @returns {void}
|
|
145
118
|
*/
|
|
146
|
-
_attachSocketEventListeners: function _attachSocketEventListeners(socket
|
|
119
|
+
_attachSocketEventListeners: function _attachSocketEventListeners(socket) {
|
|
147
120
|
var _this2 = this;
|
|
148
121
|
socket.on('close', function (event) {
|
|
149
|
-
return _this2._onclose(
|
|
122
|
+
return _this2._onclose(event, socket);
|
|
150
123
|
});
|
|
151
124
|
socket.on('message', function () {
|
|
152
|
-
|
|
153
|
-
args[_key] = arguments[_key];
|
|
154
|
-
}
|
|
155
|
-
return _this2._onmessage.apply(_this2, [sessionId].concat(args));
|
|
125
|
+
return _this2._onmessage.apply(_this2, arguments);
|
|
156
126
|
});
|
|
157
127
|
socket.on('pong', function () {
|
|
158
|
-
|
|
159
|
-
args[_key2] = arguments[_key2];
|
|
160
|
-
}
|
|
161
|
-
return _this2._setTimeOffset.apply(_this2, [sessionId].concat(args));
|
|
128
|
+
return _this2._setTimeOffset.apply(_this2, arguments);
|
|
162
129
|
});
|
|
163
130
|
socket.on('sequence-mismatch', function () {
|
|
164
|
-
for (var
|
|
165
|
-
args[
|
|
131
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
132
|
+
args[_key] = arguments[_key];
|
|
166
133
|
}
|
|
167
|
-
return _this2._emit.apply(_this2, [
|
|
134
|
+
return _this2._emit.apply(_this2, ['sequence-mismatch'].concat(args));
|
|
168
135
|
});
|
|
169
136
|
socket.on('ping-pong-latency', function () {
|
|
170
|
-
for (var
|
|
171
|
-
args[
|
|
137
|
+
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
138
|
+
args[_key2] = arguments[_key2];
|
|
172
139
|
}
|
|
173
|
-
return _this2._emit.apply(_this2, [
|
|
140
|
+
return _this2._emit.apply(_this2, ['ping-pong-latency'].concat(args));
|
|
174
141
|
});
|
|
175
142
|
},
|
|
176
143
|
/**
|
|
177
144
|
* Handle imminent shutdown by establishing a new connection while keeping
|
|
178
145
|
* the current one alive (make-before-break).
|
|
179
146
|
* Idempotent: will no-op if already in progress.
|
|
180
|
-
* @param {string} sessionId - The session ID for which the shutdown is imminent
|
|
181
147
|
* @returns {void}
|
|
182
148
|
*/
|
|
183
|
-
_handleImminentShutdown: function _handleImminentShutdown(
|
|
149
|
+
_handleImminentShutdown: function _handleImminentShutdown() {
|
|
184
150
|
var _this3 = this;
|
|
185
|
-
var oldSocket = this.
|
|
151
|
+
var oldSocket = this.socket;
|
|
186
152
|
try {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
if (this._shutdownSwitchoverBackoffCalls.get(sessionId)) {
|
|
190
|
-
this.logger.info("".concat(this.namespace, ": [shutdown] switchover already in progress for ").concat(sessionId));
|
|
153
|
+
if (this._shutdownSwitchoverBackoffCall) {
|
|
154
|
+
this.logger.info("".concat(this.namespace, ": [shutdown] switchover already in progress"));
|
|
191
155
|
return;
|
|
192
156
|
}
|
|
193
157
|
this._shutdownSwitchoverId = "".concat((0, _now.default)());
|
|
194
|
-
this.logger.info("".concat(this.namespace, ": [shutdown] switchover start, id=").concat(this._shutdownSwitchoverId
|
|
195
|
-
this._connectWithBackoff(undefined,
|
|
158
|
+
this.logger.info("".concat(this.namespace, ": [shutdown] switchover start, id=").concat(this._shutdownSwitchoverId));
|
|
159
|
+
this._connectWithBackoff(undefined, {
|
|
196
160
|
isShutdownSwitchover: true,
|
|
197
161
|
attemptOptions: {
|
|
198
162
|
isShutdownSwitchover: true,
|
|
199
163
|
onSuccess: function onSuccess(newSocket, webSocketUrl) {
|
|
200
|
-
_this3.logger.info("".concat(_this3.namespace, ": [shutdown] switchover connected, url: ").concat(webSocketUrl
|
|
164
|
+
_this3.logger.info("".concat(_this3.namespace, ": [shutdown] switchover connected, url: ").concat(webSocketUrl));
|
|
201
165
|
|
|
202
166
|
// Atomically switch active socket reference
|
|
203
|
-
_this3.socket =
|
|
204
|
-
_this3.connected =
|
|
167
|
+
_this3.socket = newSocket;
|
|
168
|
+
_this3.connected = true; // remain connected throughout
|
|
205
169
|
|
|
206
|
-
_this3._emit(
|
|
170
|
+
_this3._emit('event:mercury_shutdown_switchover_complete', {
|
|
207
171
|
url: webSocketUrl
|
|
208
172
|
});
|
|
209
173
|
if (oldSocket) {
|
|
@@ -212,18 +176,18 @@ var Mercury = _webexCore.WebexPlugin.extend((_dec = (0, _common.deprecated)('Mer
|
|
|
212
176
|
}
|
|
213
177
|
}
|
|
214
178
|
}).then(function () {
|
|
215
|
-
_this3.logger.info("".concat(_this3.namespace, ": [shutdown] switchover completed successfully
|
|
179
|
+
_this3.logger.info("".concat(_this3.namespace, ": [shutdown] switchover completed successfully"));
|
|
216
180
|
}).catch(function (err) {
|
|
217
|
-
_this3.logger.info("".concat(_this3.namespace, ": [shutdown] switchover exhausted retries; will fall back to normal reconnection
|
|
218
|
-
_this3._emit(
|
|
181
|
+
_this3.logger.info("".concat(_this3.namespace, ": [shutdown] switchover exhausted retries; will fall back to normal reconnection"), err);
|
|
182
|
+
_this3._emit('event:mercury_shutdown_switchover_failed', {
|
|
219
183
|
reason: err
|
|
220
184
|
});
|
|
221
185
|
// Old socket will eventually close with 4001, triggering normal reconnection
|
|
222
186
|
});
|
|
223
187
|
} catch (e) {
|
|
224
|
-
this.logger.error("".concat(this.namespace, ": [shutdown] error during switchover
|
|
225
|
-
this.
|
|
226
|
-
this._emit(
|
|
188
|
+
this.logger.error("".concat(this.namespace, ": [shutdown] error during switchover"), e);
|
|
189
|
+
this._shutdownSwitchoverBackoffCall = undefined;
|
|
190
|
+
this._emit('event:mercury_shutdown_switchover_failed', {
|
|
227
191
|
reason: e
|
|
228
192
|
});
|
|
229
193
|
}
|
|
@@ -236,153 +200,57 @@ var Mercury = _webexCore.WebexPlugin.extend((_dec = (0, _common.deprecated)('Mer
|
|
|
236
200
|
return this.lastError;
|
|
237
201
|
},
|
|
238
202
|
/**
|
|
239
|
-
* Get
|
|
240
|
-
* @returns {
|
|
241
|
-
*/
|
|
242
|
-
getSockets: function getSockets() {
|
|
243
|
-
return this.sockets;
|
|
244
|
-
},
|
|
245
|
-
/**
|
|
246
|
-
* Get a specific socket by connection ID
|
|
247
|
-
* @param {string} sessionId - The connection identifier
|
|
248
|
-
* @returns {Socket|undefined} The socket instance or undefined if not found
|
|
203
|
+
* Get the underlying WebSocket.
|
|
204
|
+
* @returns {any} The socket instance, or undefined if not connected.
|
|
249
205
|
*/
|
|
250
206
|
getSocket: function getSocket() {
|
|
251
|
-
|
|
252
|
-
return this.sockets.get(sessionId);
|
|
207
|
+
return this.socket;
|
|
253
208
|
},
|
|
254
|
-
/**
|
|
255
|
-
* Check if a socket is connected
|
|
256
|
-
* @param {string} [sessionId=this.defaultSessionId] - The session identifier
|
|
257
|
-
* @returns {boolean|undefined} True if the socket is connected
|
|
258
|
-
*/
|
|
259
|
-
hasConnectedSockets: function hasConnectedSockets() {
|
|
260
|
-
var sessionId = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.defaultSessionId;
|
|
261
|
-
var socket = this.sockets.get(sessionId || this.defaultSessionId);
|
|
262
|
-
return socket === null || socket === void 0 ? void 0 : socket.connected;
|
|
263
|
-
},
|
|
264
|
-
/**
|
|
265
|
-
* Check if any sockets are connecting
|
|
266
|
-
* @param {string} [sessionId=this.defaultSessionId] - The session identifier
|
|
267
|
-
* @returns {boolean|undefined} True if the socket is connecting
|
|
268
|
-
*/
|
|
269
|
-
hasConnectingSockets: function hasConnectingSockets() {
|
|
270
|
-
var sessionId = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.defaultSessionId;
|
|
271
|
-
var socket = this.sockets.get(sessionId || this.defaultSessionId);
|
|
272
|
-
return socket === null || socket === void 0 ? void 0 : socket.connecting;
|
|
273
|
-
},
|
|
274
|
-
/**
|
|
275
|
-
* Connect to Mercury for a specific session.
|
|
276
|
-
* @param {string} [webSocketUrl] - Optional websocket URL override. Falls back to the device websocket URL.
|
|
277
|
-
* @param {string} [sessionId=this.defaultSessionId] - The session identifier for this connection.
|
|
278
|
-
* @returns {Promise<void>} Resolves when connection flow completes for the session.
|
|
279
|
-
*/
|
|
280
209
|
connect: function connect(webSocketUrl) {
|
|
281
210
|
var _this4 = this;
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
// First check if there's already a connection promise for this session
|
|
286
|
-
if (this._connectPromises.has(sessionId)) {
|
|
287
|
-
this.logger.info("".concat(this.namespace, ": connection ").concat(sessionId, " already in progress, returning existing promise"));
|
|
288
|
-
return this._connectPromises.get(sessionId);
|
|
289
|
-
}
|
|
290
|
-
var sessionSocket = this.sockets.get(sessionId);
|
|
291
|
-
if (sessionSocket !== null && sessionSocket !== void 0 && sessionSocket.connected || sessionSocket !== null && sessionSocket !== void 0 && sessionSocket.connecting) {
|
|
292
|
-
this.logger.info("".concat(this.namespace, ": connection ").concat(sessionId, " already connected, will not connect again"));
|
|
211
|
+
if (this.connected) {
|
|
212
|
+
this.logger.info("".concat(this.namespace, ": already connected, will not connect again"));
|
|
293
213
|
return _promise.default.resolve();
|
|
294
214
|
}
|
|
215
|
+
|
|
216
|
+
// If already connecting, return the existing promise so callers can await it
|
|
217
|
+
if (this._connectPromise) {
|
|
218
|
+
this.logger.info("".concat(this.namespace, ": connection already in progress, returning existing promise"));
|
|
219
|
+
return this._connectPromise;
|
|
220
|
+
}
|
|
295
221
|
this.connecting = true;
|
|
296
|
-
this.logger.info("".concat(this.namespace, ": starting connection attempt
|
|
297
|
-
this.
|
|
298
|
-
|
|
299
|
-
_this4.
|
|
300
|
-
return _this4._connectWithBackoff(webSocketUrl, sessionId);
|
|
222
|
+
this.logger.info("".concat(this.namespace, ": starting connection attempt"));
|
|
223
|
+
this._connectPromise = _promise.default.resolve(this.webex.internal.device.registered || this.webex.internal.device.register()).then(function () {
|
|
224
|
+
_this4.logger.info("".concat(_this4.namespace, ": connecting"));
|
|
225
|
+
return _this4._connectWithBackoff(webSocketUrl);
|
|
301
226
|
}).finally(function () {
|
|
302
|
-
_this4.
|
|
227
|
+
_this4._connectPromise = null;
|
|
303
228
|
});
|
|
304
|
-
this.
|
|
305
|
-
return connectPromise;
|
|
306
|
-
},
|
|
307
|
-
logout: function logout() {
|
|
308
|
-
this.logger.info("".concat(this.namespace, ": logout() called"));
|
|
309
|
-
this.logger.info("".concat(this.namespace, ": debug_mercury_logging stack: "), new Error('debug_mercury_logging').stack);
|
|
310
|
-
return this.disconnectAll(this.config.beforeLogoutOptionsCloseReason && !normalReconnectReasons.includes(this.config.beforeLogoutOptionsCloseReason) ? {
|
|
311
|
-
code: 3050,
|
|
312
|
-
reason: this.config.beforeLogoutOptionsCloseReason
|
|
313
|
-
} : undefined);
|
|
229
|
+
return this._connectPromise;
|
|
314
230
|
},
|
|
315
|
-
/**
|
|
316
|
-
* Disconnect a Mercury socket for a specific session.
|
|
317
|
-
* @param {object} [options] - Optional websocket close options (for example: `{code, reason}`).
|
|
318
|
-
* @param {string} [sessionId=this.defaultSessionId] - The session identifier to disconnect.
|
|
319
|
-
* @returns {Promise<void>} Resolves after disconnect cleanup and close handling are initiated/completed.
|
|
320
|
-
*/
|
|
321
231
|
disconnect: function disconnect(options) {
|
|
322
232
|
var _this5 = this;
|
|
323
|
-
var sessionId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.defaultSessionId;
|
|
324
233
|
this.logger.info("".concat(this.namespace, "#disconnect: connecting state: ").concat(this.connecting, ", connected state: ").concat(this.connected, ", socket exists: ").concat(!!this.socket, ", options: ").concat((0, _stringify.default)(options)));
|
|
325
234
|
return new _promise.default(function (resolve) {
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
_this5.
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
_this5.
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
_this5.
|
|
341
|
-
|
|
342
|
-
var sessionSocket = _this5.sockets.get(sessionId);
|
|
343
|
-
var suffix = sessionId === _this5.defaultSessionId ? '' : ":".concat(sessionId);
|
|
344
|
-
if (sessionSocket) {
|
|
345
|
-
sessionSocket.removeAllListeners('message');
|
|
346
|
-
sessionSocket.connecting = false;
|
|
347
|
-
sessionSocket.connected = false;
|
|
348
|
-
_this5.once(sessionId === _this5.defaultSessionId ? 'offline' : "offline".concat(suffix), resolve);
|
|
349
|
-
resolve(sessionSocket.close(options || undefined));
|
|
235
|
+
if (_this5.backoffCall) {
|
|
236
|
+
_this5.logger.info("".concat(_this5.namespace, ": aborting connection"));
|
|
237
|
+
_this5.backoffCall.abort();
|
|
238
|
+
}
|
|
239
|
+
if (_this5._shutdownSwitchoverBackoffCall) {
|
|
240
|
+
_this5.logger.info("".concat(_this5.namespace, ": aborting shutdown switchover"));
|
|
241
|
+
_this5._shutdownSwitchoverBackoffCall.abort();
|
|
242
|
+
}
|
|
243
|
+
if (_this5.socket) {
|
|
244
|
+
_this5.socket.removeAllListeners('message');
|
|
245
|
+
_this5.once('offline', function () {
|
|
246
|
+
_this5._emit('disconnected');
|
|
247
|
+
resolve();
|
|
248
|
+
});
|
|
249
|
+
_this5.socket.close(options);
|
|
250
|
+
return;
|
|
350
251
|
}
|
|
252
|
+
_this5._emit('disconnected');
|
|
351
253
|
resolve();
|
|
352
|
-
|
|
353
|
-
// Update overall connected status
|
|
354
|
-
_this5.connected = _this5.hasConnectedSockets();
|
|
355
|
-
});
|
|
356
|
-
},
|
|
357
|
-
/**
|
|
358
|
-
* Disconnect all socket connections
|
|
359
|
-
* @param {object} options - Close options
|
|
360
|
-
* @returns {Promise} Promise that resolves when all connections are closed
|
|
361
|
-
*/
|
|
362
|
-
disconnectAll: function disconnectAll(options) {
|
|
363
|
-
var _this6 = this;
|
|
364
|
-
var disconnectPromises = [];
|
|
365
|
-
var _iterator = _createForOfIteratorHelper(this.sockets.keys()),
|
|
366
|
-
_step;
|
|
367
|
-
try {
|
|
368
|
-
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
369
|
-
var sessionId = _step.value;
|
|
370
|
-
disconnectPromises.push(this.disconnect(options, sessionId));
|
|
371
|
-
}
|
|
372
|
-
} catch (err) {
|
|
373
|
-
_iterator.e(err);
|
|
374
|
-
} finally {
|
|
375
|
-
_iterator.f();
|
|
376
|
-
}
|
|
377
|
-
return _promise.default.all(disconnectPromises).then(function () {
|
|
378
|
-
_this6.connected = false;
|
|
379
|
-
_this6.sockets.clear();
|
|
380
|
-
_this6.sessionWebSocketUrls.clear();
|
|
381
|
-
_this6.backoffCalls.clear();
|
|
382
|
-
// Clear connection promises to prevent stale promises
|
|
383
|
-
if (_this6._connectPromises) {
|
|
384
|
-
_this6._connectPromises.clear();
|
|
385
|
-
}
|
|
386
254
|
});
|
|
387
255
|
},
|
|
388
256
|
listen: function listen() {
|
|
@@ -406,7 +274,7 @@ var Mercury = _webexCore.WebexPlugin.extend((_dec = (0, _common.deprecated)('Mer
|
|
|
406
274
|
});
|
|
407
275
|
},
|
|
408
276
|
_prepareUrl: function _prepareUrl(webSocketUrl) {
|
|
409
|
-
var
|
|
277
|
+
var _this6 = this;
|
|
410
278
|
if (!webSocketUrl) {
|
|
411
279
|
webSocketUrl = this.webex.internal.device.webSocketUrl;
|
|
412
280
|
}
|
|
@@ -414,16 +282,16 @@ var Mercury = _webexCore.WebexPlugin.extend((_dec = (0, _common.deprecated)('Mer
|
|
|
414
282
|
if (haMessagingEnabled) {
|
|
415
283
|
var highPrioritySocketUrl;
|
|
416
284
|
try {
|
|
417
|
-
highPrioritySocketUrl =
|
|
285
|
+
highPrioritySocketUrl = _this6.webex.internal.services.convertUrlToPriorityHostUrl(webSocketUrl);
|
|
418
286
|
} catch (e) {
|
|
419
|
-
|
|
287
|
+
_this6.logger.warn("".concat(_this6.namespace, ": error converting to high priority url"), e);
|
|
420
288
|
}
|
|
421
289
|
if (!highPrioritySocketUrl) {
|
|
422
290
|
var _url$parse;
|
|
423
291
|
var hostFromUrl = (_url$parse = _url.default.parse(webSocketUrl, true)) === null || _url$parse === void 0 ? void 0 : _url$parse.host;
|
|
424
|
-
var isValidHost =
|
|
292
|
+
var isValidHost = _this6.webex.internal.services.isValidHost(hostFromUrl);
|
|
425
293
|
if (!isValidHost) {
|
|
426
|
-
|
|
294
|
+
_this6.logger.error("".concat(_this6.namespace, ": host ").concat(hostFromUrl, " is not a valid host from host catalog"));
|
|
427
295
|
return '';
|
|
428
296
|
}
|
|
429
297
|
}
|
|
@@ -433,7 +301,7 @@ var Mercury = _webexCore.WebexPlugin.extend((_dec = (0, _common.deprecated)('Mer
|
|
|
433
301
|
}).then(function (wsUrl) {
|
|
434
302
|
webSocketUrl = wsUrl;
|
|
435
303
|
}).then(function () {
|
|
436
|
-
return
|
|
304
|
+
return _this6.webex.internal.feature.getFeature('developer', 'web-shared-mercury');
|
|
437
305
|
}).then(function (webSharedMercury) {
|
|
438
306
|
if (!webSocketUrl) {
|
|
439
307
|
return '';
|
|
@@ -451,7 +319,7 @@ var Mercury = _webexCore.WebexPlugin.extend((_dec = (0, _common.deprecated)('Mer
|
|
|
451
319
|
});
|
|
452
320
|
(0, _deleteProperty.default)(webSocketUrl.query, 'bufferStates');
|
|
453
321
|
}
|
|
454
|
-
if ((0, _lodash.get)(
|
|
322
|
+
if ((0, _lodash.get)(_this6, 'webex.config.device.ephemeral', false)) {
|
|
455
323
|
webSocketUrl.query.multipleConnections = true;
|
|
456
324
|
}
|
|
457
325
|
webSocketUrl.query.clientTimestamp = (0, _now.default)();
|
|
@@ -459,23 +327,20 @@ var Mercury = _webexCore.WebexPlugin.extend((_dec = (0, _common.deprecated)('Mer
|
|
|
459
327
|
return _url.default.format(webSocketUrl);
|
|
460
328
|
});
|
|
461
329
|
},
|
|
462
|
-
_attemptConnection: function _attemptConnection(socketUrl,
|
|
463
|
-
var
|
|
464
|
-
var options = arguments.length >
|
|
330
|
+
_attemptConnection: function _attemptConnection(socketUrl, callback) {
|
|
331
|
+
var _this7 = this;
|
|
332
|
+
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
465
333
|
var _options$isShutdownSw = options.isShutdownSwitchover,
|
|
466
334
|
isShutdownSwitchover = _options$isShutdownSw === void 0 ? false : _options$isShutdownSw,
|
|
467
335
|
_options$onSuccess = options.onSuccess,
|
|
468
336
|
onSuccess = _options$onSuccess === void 0 ? null : _options$onSuccess;
|
|
469
337
|
var socket = new _socket.default();
|
|
470
|
-
socket.connecting = true;
|
|
471
338
|
var newWSUrl;
|
|
472
|
-
this._attachSocketEventListeners(socket
|
|
473
|
-
var backoffCall = isShutdownSwitchover ? this._shutdownSwitchoverBackoffCalls.get(sessionId) : this.backoffCalls.get(sessionId);
|
|
339
|
+
this._attachSocketEventListeners(socket);
|
|
474
340
|
|
|
475
341
|
// Check appropriate backoff call based on connection type
|
|
476
|
-
if (!
|
|
477
|
-
var
|
|
478
|
-
var msg = "".concat(this.namespace, ": prevent socket open when ").concat(mode, " no longer defined for ").concat(sessionId);
|
|
342
|
+
if (isShutdownSwitchover && !this._shutdownSwitchoverBackoffCall) {
|
|
343
|
+
var msg = "".concat(this.namespace, ": prevent socket open when switchover backoff call no longer defined");
|
|
479
344
|
var err = new Error(msg);
|
|
480
345
|
this.logger.info(msg);
|
|
481
346
|
|
|
@@ -483,15 +348,26 @@ var Mercury = _webexCore.WebexPlugin.extend((_dec = (0, _common.deprecated)('Mer
|
|
|
483
348
|
callback(err);
|
|
484
349
|
return _promise.default.reject(err);
|
|
485
350
|
}
|
|
351
|
+
if (!isShutdownSwitchover && !this.backoffCall) {
|
|
352
|
+
var _msg = "".concat(this.namespace, ": prevent socket open when backoffCall no longer defined");
|
|
353
|
+
var _err = new Error(_msg);
|
|
354
|
+
this.logger.info(_msg);
|
|
355
|
+
|
|
356
|
+
// Call the callback with the error before rejecting
|
|
357
|
+
callback(_err);
|
|
358
|
+
|
|
359
|
+
// eslint-disable-next-line no-unreachable
|
|
360
|
+
return _promise.default.reject(_err);
|
|
361
|
+
}
|
|
486
362
|
|
|
487
363
|
// For shutdown switchover, don't set socket yet (make-before-break)
|
|
488
364
|
// For normal connection, set socket before opening to allow disconnect() to close it
|
|
489
365
|
if (!isShutdownSwitchover) {
|
|
490
|
-
this.
|
|
366
|
+
this.socket = socket;
|
|
491
367
|
}
|
|
492
|
-
return this._prepareAndOpenSocket(socket, socketUrl,
|
|
368
|
+
return this._prepareAndOpenSocket(socket, socketUrl, isShutdownSwitchover).then(function (webSocketUrl) {
|
|
493
369
|
newWSUrl = webSocketUrl;
|
|
494
|
-
|
|
370
|
+
_this7.logger.info("".concat(_this7.namespace, ": ").concat(isShutdownSwitchover ? '[shutdown] switchover' : '', " connected to mercury, success, action: connected, url: ").concat(newWSUrl));
|
|
495
371
|
|
|
496
372
|
// Custom success handler for shutdown switchover
|
|
497
373
|
if (onSuccess) {
|
|
@@ -502,46 +378,46 @@ var Mercury = _webexCore.WebexPlugin.extend((_dec = (0, _common.deprecated)('Mer
|
|
|
502
378
|
|
|
503
379
|
// Default behavior for normal connection
|
|
504
380
|
callback();
|
|
505
|
-
return
|
|
381
|
+
return _this7.webex.internal.feature.getFeature('developer', 'web-high-availability').then(function (haMessagingEnabled) {
|
|
506
382
|
if (haMessagingEnabled) {
|
|
507
|
-
return
|
|
383
|
+
return _this7.webex.internal.device.refresh();
|
|
508
384
|
}
|
|
509
385
|
return _promise.default.resolve();
|
|
510
386
|
});
|
|
511
387
|
}).catch(function (reason) {
|
|
388
|
+
var _this7$backoffCall, _this7$backoffCall3;
|
|
512
389
|
// For shutdown, simpler error handling - just callback for retry
|
|
513
390
|
if (isShutdownSwitchover) {
|
|
514
|
-
|
|
391
|
+
_this7.logger.info("".concat(_this7.namespace, ": [shutdown] switchover attempt failed"), reason);
|
|
515
392
|
return callback(reason);
|
|
516
393
|
}
|
|
517
394
|
|
|
518
395
|
// Normal connection error handling (existing complex logic)
|
|
519
|
-
|
|
396
|
+
_this7.lastError = reason; // remember the last error
|
|
520
397
|
|
|
521
|
-
var backoffCallNormal = _this8.backoffCalls.get(sessionId);
|
|
522
398
|
// Suppress connection errors that appear to be network related. This
|
|
523
399
|
// may end up suppressing metrics during outages, but we might not care
|
|
524
400
|
// (especially since many of our outages happen in a way that client
|
|
525
401
|
// metrics can't be trusted).
|
|
526
|
-
if (reason.code !== 1006 &&
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
retries:
|
|
402
|
+
if (reason.code !== 1006 && _this7.backoffCall && ((_this7$backoffCall = _this7.backoffCall) === null || _this7$backoffCall === void 0 ? void 0 : _this7$backoffCall.getNumRetries()) > 0) {
|
|
403
|
+
var _this7$backoffCall2;
|
|
404
|
+
_this7._emit('connection_failed', reason, {
|
|
405
|
+
retries: (_this7$backoffCall2 = _this7.backoffCall) === null || _this7$backoffCall2 === void 0 ? void 0 : _this7$backoffCall2.getNumRetries()
|
|
530
406
|
});
|
|
531
407
|
}
|
|
532
|
-
|
|
408
|
+
_this7.logger.info("".concat(_this7.namespace, ": connection attempt failed"), reason, ((_this7$backoffCall3 = _this7.backoffCall) === null || _this7$backoffCall3 === void 0 ? void 0 : _this7$backoffCall3.getNumRetries()) === 0 ? reason.stack : '');
|
|
533
409
|
// UnknownResponse is produced by IE for any 4XXX; treated it like a bad
|
|
534
410
|
// web socket url and let WDM handle the token checking
|
|
535
411
|
if (reason instanceof _errors.UnknownResponse) {
|
|
536
|
-
|
|
537
|
-
return
|
|
412
|
+
_this7.logger.info("".concat(_this7.namespace, ": received unknown response code, refreshing device registration"));
|
|
413
|
+
return _this7.webex.internal.device.refresh().then(function () {
|
|
538
414
|
return callback(reason);
|
|
539
415
|
});
|
|
540
416
|
}
|
|
541
417
|
// NotAuthorized implies expired token
|
|
542
418
|
if (reason instanceof _errors.NotAuthorized) {
|
|
543
|
-
|
|
544
|
-
return
|
|
419
|
+
_this7.logger.info("".concat(_this7.namespace, ": received authorization error, reauthorizing"));
|
|
420
|
+
return _this7.webex.credentials.refresh({
|
|
545
421
|
force: true
|
|
546
422
|
}).then(function () {
|
|
547
423
|
return callback(reason);
|
|
@@ -556,20 +432,20 @@ var Mercury = _webexCore.WebexPlugin.extend((_dec = (0, _common.deprecated)('Mer
|
|
|
556
432
|
// BadRequest implies current credentials are for a Service Account
|
|
557
433
|
// Forbidden implies current user is not entitle for Webex
|
|
558
434
|
if (reason instanceof _errors.BadRequest || reason instanceof _errors.Forbidden) {
|
|
559
|
-
|
|
560
|
-
|
|
435
|
+
_this7.logger.warn("".concat(_this7.namespace, ": received unrecoverable response from mercury"));
|
|
436
|
+
_this7.backoffCall.abort();
|
|
561
437
|
return callback(reason);
|
|
562
438
|
}
|
|
563
439
|
if (reason instanceof _errors.ConnectionError) {
|
|
564
|
-
return
|
|
440
|
+
return _this7.webex.internal.feature.getFeature('developer', 'web-high-availability').then(function (haMessagingEnabled) {
|
|
565
441
|
var wsUrl = newWSUrl || reason.webSocketUrl;
|
|
566
442
|
if (haMessagingEnabled) {
|
|
567
|
-
|
|
443
|
+
_this7.logger.info("".concat(_this7.namespace, ": received a generic connection error, will try to connect to another datacenter. failed, action: 'failed', url: ").concat(wsUrl, " error: ").concat(reason.message));
|
|
568
444
|
if (wsUrl) {
|
|
569
|
-
|
|
570
|
-
return
|
|
445
|
+
_this7.logger.info("".concat(_this7.namespace, ": marking ").concat(wsUrl, " as failed due to connection error"));
|
|
446
|
+
return _this7.webex.internal.services.markFailedUrl(wsUrl);
|
|
571
447
|
}
|
|
572
|
-
|
|
448
|
+
_this7.logger.info("".concat(_this7.namespace, ": no socket url available to mark as failed due to connection error"));
|
|
573
449
|
}
|
|
574
450
|
return null;
|
|
575
451
|
}).then(function () {
|
|
@@ -578,45 +454,39 @@ var Mercury = _webexCore.WebexPlugin.extend((_dec = (0, _common.deprecated)('Mer
|
|
|
578
454
|
}
|
|
579
455
|
return callback(reason);
|
|
580
456
|
}).catch(function (reason) {
|
|
581
|
-
|
|
457
|
+
_this7.logger.error("".concat(_this7.namespace, ": failed to handle connection failure"), reason);
|
|
582
458
|
callback(reason);
|
|
583
459
|
});
|
|
584
460
|
},
|
|
585
|
-
_prepareAndOpenSocket: function _prepareAndOpenSocket(socket, socketUrl
|
|
586
|
-
var
|
|
587
|
-
var isShutdownSwitchover = arguments.length >
|
|
461
|
+
_prepareAndOpenSocket: function _prepareAndOpenSocket(socket, socketUrl) {
|
|
462
|
+
var _this8 = this;
|
|
463
|
+
var isShutdownSwitchover = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
588
464
|
var logPrefix = isShutdownSwitchover ? '[shutdown] switchover' : 'connection';
|
|
589
465
|
return _promise.default.all([this._prepareUrl(socketUrl), this.webex.credentials.getUserToken()]).then(function (_ref) {
|
|
590
466
|
var _ref2 = (0, _slicedToArray2.default)(_ref, 2),
|
|
591
467
|
webSocketUrl = _ref2[0],
|
|
592
468
|
token = _ref2[1];
|
|
593
469
|
var options = {
|
|
594
|
-
forceCloseDelay:
|
|
595
|
-
pingInterval:
|
|
596
|
-
pongTimeout:
|
|
470
|
+
forceCloseDelay: _this8.config.forceCloseDelay,
|
|
471
|
+
pingInterval: _this8.config.pingInterval,
|
|
472
|
+
pongTimeout: _this8.config.pongTimeout,
|
|
597
473
|
token: token.toString(),
|
|
598
|
-
trackingId: "".concat(
|
|
599
|
-
logger:
|
|
474
|
+
trackingId: "".concat(_this8.webex.sessionId, "_").concat((0, _now.default)()),
|
|
475
|
+
logger: _this8.logger
|
|
600
476
|
};
|
|
601
|
-
if (
|
|
477
|
+
if (_this8.webex.config.defaultMercuryOptions) {
|
|
602
478
|
var customOptionsMsg = isShutdownSwitchover ? 'setting custom options for switchover' : 'setting custom options';
|
|
603
|
-
|
|
604
|
-
options = _objectSpread(_objectSpread({}, options),
|
|
479
|
+
_this8.logger.info("".concat(_this8.namespace, ": ").concat(customOptionsMsg));
|
|
480
|
+
options = _objectSpread(_objectSpread({}, options), _this8.webex.config.defaultMercuryOptions);
|
|
605
481
|
}
|
|
482
|
+
_this8.logger.info("".concat(_this8.namespace, ": ").concat(logPrefix, " url: ").concat(webSocketUrl));
|
|
606
483
|
|
|
607
|
-
//
|
|
608
|
-
//
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
// Remember the resolved URL used to open this socket so that
|
|
614
|
-
// reconnection in _onclose re-derives from a catalog-valid host. This is
|
|
615
|
-
// captured before socket.open(), which a lower layer (e.g. the same-site
|
|
616
|
-
// websocket proxy done with interceptors) may rewrite into a non-catalog host.
|
|
617
|
-
// Reusing the post-proxy native socket URL would fail
|
|
618
|
-
// host-catalog validation in _prepareUrl and block reconnection.
|
|
619
|
-
_this9.sessionWebSocketUrls.set(sessionId, webSocketUrl);
|
|
484
|
+
// Store the resolved URL before socket.open(), which may be rewritten by
|
|
485
|
+
// an interceptor (e.g. same-site websocket proxy). On reconnection we need
|
|
486
|
+
// the original catalog-valid URL, not the post-proxy one from socket.url.
|
|
487
|
+
if (!isShutdownSwitchover) {
|
|
488
|
+
_this8.resolvedWebSocketUrl = webSocketUrl;
|
|
489
|
+
}
|
|
620
490
|
return socket.open(webSocketUrl, options).then(function () {
|
|
621
491
|
return webSocketUrl;
|
|
622
492
|
}).catch(function (err) {
|
|
@@ -625,126 +495,93 @@ var Mercury = _webexCore.WebexPlugin.extend((_dec = (0, _common.deprecated)('Mer
|
|
|
625
495
|
});
|
|
626
496
|
});
|
|
627
497
|
},
|
|
628
|
-
_connectWithBackoff: function _connectWithBackoff(webSocketUrl
|
|
629
|
-
var
|
|
630
|
-
var context = arguments.length >
|
|
498
|
+
_connectWithBackoff: function _connectWithBackoff(webSocketUrl) {
|
|
499
|
+
var _this9 = this;
|
|
500
|
+
var context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
631
501
|
var _context$isShutdownSw = context.isShutdownSwitchover,
|
|
632
502
|
isShutdownSwitchover = _context$isShutdownSw === void 0 ? false : _context$isShutdownSw,
|
|
633
503
|
_context$attemptOptio = context.attemptOptions,
|
|
634
504
|
attemptOptions = _context$attemptOptio === void 0 ? {} : _context$attemptOptio;
|
|
635
505
|
return new _promise.default(function (resolve, reject) {
|
|
636
|
-
// eslint gets confused about whether call is actually used
|
|
506
|
+
// eslint gets confused about whether or not call is actually used
|
|
637
507
|
// eslint-disable-next-line prefer-const
|
|
638
508
|
var call;
|
|
639
509
|
var onComplete = function onComplete(err) {
|
|
640
|
-
|
|
510
|
+
// Clear state flags based on connection type
|
|
641
511
|
if (isShutdownSwitchover) {
|
|
642
|
-
|
|
512
|
+
_this9._shutdownSwitchoverBackoffCall = undefined;
|
|
643
513
|
} else {
|
|
644
|
-
|
|
514
|
+
_this9.connecting = false;
|
|
515
|
+
_this9.backoffCall = undefined;
|
|
645
516
|
}
|
|
646
|
-
var sessionSocket = _this0.sockets.get(sid);
|
|
647
517
|
if (err) {
|
|
648
518
|
var msg = isShutdownSwitchover ? "[shutdown] switchover failed after ".concat(call.getNumRetries(), " retries") : "failed to connect after ".concat(call.getNumRetries(), " retries");
|
|
649
|
-
|
|
650
|
-
if (sessionSocket) {
|
|
651
|
-
sessionSocket.connecting = false;
|
|
652
|
-
sessionSocket.connected = false;
|
|
653
|
-
}
|
|
519
|
+
_this9.logger.info("".concat(_this9.namespace, ": ").concat(msg, "; log statement about next retry was inaccurate; ").concat(err));
|
|
654
520
|
return reject(err);
|
|
655
521
|
}
|
|
656
522
|
|
|
657
|
-
// Update overall connected status
|
|
658
|
-
if (sessionSocket) {
|
|
659
|
-
sessionSocket.connecting = false;
|
|
660
|
-
sessionSocket.connected = true;
|
|
661
|
-
}
|
|
662
523
|
// Default success handling for normal connections
|
|
663
524
|
if (!isShutdownSwitchover) {
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
if (_this0.connected) {
|
|
669
|
-
_this0.webex.internal.newMetrics.callDiagnosticMetrics.setMercuryConnectedStatus(true);
|
|
670
|
-
}
|
|
525
|
+
_this9.connected = true;
|
|
526
|
+
_this9.hasEverConnected = true;
|
|
527
|
+
_this9._emit('online');
|
|
528
|
+
_this9.webex.internal.newMetrics.callDiagnosticMetrics.setMercuryConnectedStatus(true);
|
|
671
529
|
}
|
|
672
530
|
return resolve();
|
|
673
531
|
};
|
|
532
|
+
|
|
674
533
|
// eslint-disable-next-line prefer-reflect
|
|
675
534
|
call = _backoff.default.call(function (callback) {
|
|
676
535
|
var attemptNum = call.getNumRetries();
|
|
677
536
|
var logPrefix = isShutdownSwitchover ? '[shutdown] switchover' : 'connection';
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
},
|
|
681
|
-
return onComplete(err, sessionId);
|
|
682
|
-
});
|
|
537
|
+
_this9.logger.info("".concat(_this9.namespace, ": executing ").concat(logPrefix, " attempt ").concat(attemptNum));
|
|
538
|
+
_this9._attemptConnection(webSocketUrl, callback, attemptOptions);
|
|
539
|
+
}, onComplete);
|
|
683
540
|
call.setStrategy(new _backoff.default.ExponentialStrategy({
|
|
684
|
-
initialDelay:
|
|
685
|
-
maxDelay:
|
|
541
|
+
initialDelay: _this9.config.backoffTimeReset,
|
|
542
|
+
maxDelay: _this9.config.backoffTimeMax
|
|
686
543
|
}));
|
|
687
|
-
if (
|
|
688
|
-
call.failAfter(
|
|
689
|
-
} else if (
|
|
690
|
-
call.failAfter(
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
// Store the call BEFORE setting up event handlers to prevent race conditions
|
|
694
|
-
// Store backoff call reference BEFORE starting (so it's available in _attemptConnection)
|
|
695
|
-
if (isShutdownSwitchover) {
|
|
696
|
-
_this0._shutdownSwitchoverBackoffCalls.set(sessionId, call);
|
|
697
|
-
} else {
|
|
698
|
-
_this0.backoffCalls.set(sessionId, call);
|
|
544
|
+
if (_this9.config.initialConnectionMaxRetries && !_this9.hasEverConnected && !isShutdownSwitchover) {
|
|
545
|
+
call.failAfter(_this9.config.initialConnectionMaxRetries);
|
|
546
|
+
} else if (_this9.config.maxRetries) {
|
|
547
|
+
call.failAfter(_this9.config.maxRetries);
|
|
699
548
|
}
|
|
700
549
|
call.on('abort', function () {
|
|
701
550
|
var msg = isShutdownSwitchover ? 'Shutdown Switchover' : 'Connection';
|
|
702
|
-
|
|
703
|
-
reject(new Error("Mercury ".concat(msg, " Aborted
|
|
551
|
+
_this9.logger.info("".concat(_this9.namespace, ": ").concat(msg, " aborted"));
|
|
552
|
+
reject(new Error("Mercury ".concat(msg, " Aborted")));
|
|
704
553
|
});
|
|
705
554
|
call.on('callback', function (err) {
|
|
706
555
|
if (err) {
|
|
707
556
|
var number = call.getNumRetries();
|
|
708
|
-
var delay = Math.min(call.strategy_.nextBackoffDelay_,
|
|
557
|
+
var delay = Math.min(call.strategy_.nextBackoffDelay_, _this9.config.backoffTimeMax);
|
|
709
558
|
var logPrefix = isShutdownSwitchover ? '[shutdown] switchover' : '';
|
|
710
|
-
|
|
559
|
+
_this9.logger.info("".concat(_this9.namespace, ": ").concat(logPrefix, " failed to connect; attempting retry ").concat(number + 1, " in ").concat(delay, " ms"));
|
|
711
560
|
/* istanbul ignore if */
|
|
712
561
|
if (process.env.NODE_ENV === 'development') {
|
|
713
|
-
|
|
562
|
+
_this9.logger.debug("".concat(_this9.namespace, ": "), err, err.stack);
|
|
714
563
|
}
|
|
715
564
|
return;
|
|
716
565
|
}
|
|
717
|
-
|
|
566
|
+
_this9.logger.info("".concat(_this9.namespace, ": connected"));
|
|
718
567
|
});
|
|
568
|
+
|
|
569
|
+
// Store backoff call reference BEFORE starting (so it's available in _attemptConnection)
|
|
570
|
+
if (isShutdownSwitchover) {
|
|
571
|
+
_this9._shutdownSwitchoverBackoffCall = call;
|
|
572
|
+
} else {
|
|
573
|
+
_this9.backoffCall = call;
|
|
574
|
+
}
|
|
719
575
|
call.start();
|
|
720
576
|
});
|
|
721
577
|
},
|
|
722
578
|
_emit: function _emit() {
|
|
723
|
-
for (var
|
|
724
|
-
args[
|
|
579
|
+
for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
|
|
580
|
+
args[_key3] = arguments[_key3];
|
|
725
581
|
}
|
|
726
582
|
try {
|
|
727
|
-
|
|
728
|
-
return;
|
|
729
|
-
}
|
|
730
|
-
|
|
731
|
-
// New signature: _emit(sessionId, eventName, ...rest)
|
|
732
|
-
// Backwards compatibility: if the first arg isn't a known sessionId (or defaultSessionId),
|
|
733
|
-
// treat the call as the old signature and forward directly to trigger(...)
|
|
734
|
-
var first = args[0],
|
|
735
|
-
second = args[1],
|
|
736
|
-
rest = _arrayLikeToArray(args).slice(2);
|
|
737
|
-
if (typeof first === 'string' && typeof second === 'string') {
|
|
738
|
-
var sessionId = first;
|
|
739
|
-
var eventName = second;
|
|
740
|
-
var suffix = sessionId === this.defaultSessionId ? '' : ":".concat(sessionId);
|
|
741
|
-
this.trigger.apply(this, ["".concat(eventName).concat(suffix)].concat((0, _toConsumableArray2.default)(rest)));
|
|
742
|
-
} else {
|
|
743
|
-
// Old usage: _emit(eventName, ...args)
|
|
744
|
-
this.trigger.apply(this, args);
|
|
745
|
-
}
|
|
583
|
+
this.trigger.apply(this, args);
|
|
746
584
|
} catch (error) {
|
|
747
|
-
// Safely handle errors without causing additional issues during cleanup
|
|
748
585
|
try {
|
|
749
586
|
this.logger.error("".concat(this.namespace, ": error occurred in event handler:"), error, ' with args: ', args);
|
|
750
587
|
} catch (logError) {
|
|
@@ -775,7 +612,7 @@ var Mercury = _webexCore.WebexPlugin.extend((_dec = (0, _common.deprecated)('Mer
|
|
|
775
612
|
}
|
|
776
613
|
return handlers;
|
|
777
614
|
},
|
|
778
|
-
_submitMercuryClose4000Metric: function _submitMercuryClose4000Metric(
|
|
615
|
+
_submitMercuryClose4000Metric: function _submitMercuryClose4000Metric(event, options) {
|
|
779
616
|
var action = options.action,
|
|
780
617
|
isActiveSocket = options.isActiveSocket,
|
|
781
618
|
messageType = options.messageType;
|
|
@@ -786,8 +623,7 @@ var Mercury = _webexCore.WebexPlugin.extend((_dec = (0, _common.deprecated)('Mer
|
|
|
786
623
|
close_code: event.code,
|
|
787
624
|
close_reason: event.reason || '',
|
|
788
625
|
is_active_socket: isActiveSocket,
|
|
789
|
-
message_type: messageType
|
|
790
|
-
session_id: sessionId
|
|
626
|
+
message_type: messageType
|
|
791
627
|
},
|
|
792
628
|
tags: {
|
|
793
629
|
action: action,
|
|
@@ -798,40 +634,29 @@ var Mercury = _webexCore.WebexPlugin.extend((_dec = (0, _common.deprecated)('Mer
|
|
|
798
634
|
this.logger.warn("".concat(this.namespace, ": failed to submit Mercury 4000 close metric"), error);
|
|
799
635
|
}
|
|
800
636
|
},
|
|
801
|
-
_onclose: function _onclose(
|
|
637
|
+
_onclose: function _onclose(event, sourceSocket) {
|
|
802
638
|
// I don't see any way to avoid the complexity or statement count in here.
|
|
803
639
|
/* eslint complexity: [0] */
|
|
804
640
|
|
|
805
641
|
try {
|
|
642
|
+
var isActiveSocket = sourceSocket === this.socket;
|
|
806
643
|
var reason = event.reason && event.reason.toLowerCase();
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
// opened with, captured in _prepareAndOpenSocket. Do NOT reuse
|
|
812
|
-
// sourceSocket.url: that reflects the URL the native WebSocket was
|
|
813
|
-
// actually opened with, which a lower layer may have rewritten
|
|
814
|
-
// (e.g. via interceptors) into a host that is not in the SDK host
|
|
815
|
-
// catalog. Feeding such a URL back into _prepareUrl fails host-catalog
|
|
816
|
-
// validation and permanently blocks reconnection.
|
|
817
|
-
var socketUrl = this.sessionWebSocketUrls.get(sessionId);
|
|
818
|
-
this.sockets.delete(sessionId);
|
|
644
|
+
|
|
645
|
+
// Use the stored resolved URL for reconnection instead of sourceSocket.url,
|
|
646
|
+
// which may have been rewritten by an interceptor to a non-catalog host.
|
|
647
|
+
var socketUrl = this.resolvedWebSocketUrl || sourceSocket && sourceSocket.url;
|
|
819
648
|
if (isActiveSocket) {
|
|
820
649
|
// Only tear down state if the currently active socket closed
|
|
821
|
-
if (
|
|
822
|
-
|
|
823
|
-
if (sessionId === this.defaultSessionId) this.unset('socket');
|
|
824
|
-
this._emit(sessionId, 'offline', event);
|
|
825
|
-
}
|
|
826
|
-
// Update overall connected status
|
|
827
|
-
this.connecting = this.hasConnectingSockets();
|
|
828
|
-
this.connected = this.hasConnectedSockets();
|
|
829
|
-
if (!this.connected) {
|
|
830
|
-
this.webex.internal.newMetrics.callDiagnosticMetrics.setMercuryConnectedStatus(false);
|
|
650
|
+
if (this.socket) {
|
|
651
|
+
this.socket.removeAllListeners();
|
|
831
652
|
}
|
|
653
|
+
this.unset('socket');
|
|
654
|
+
this.connected = false;
|
|
655
|
+
this._emit('offline', event);
|
|
656
|
+
this.webex.internal.newMetrics.callDiagnosticMetrics.setMercuryConnectedStatus(false);
|
|
832
657
|
} else {
|
|
833
658
|
// Old socket closed; do not flip connection state
|
|
834
|
-
this.logger.info("".concat(this.namespace, ": [shutdown] non-active socket closed, code=").concat(event.code
|
|
659
|
+
this.logger.info("".concat(this.namespace, ": [shutdown] non-active socket closed, code=").concat(event.code));
|
|
835
660
|
// Clean up listeners from old socket now that it's closed
|
|
836
661
|
if (sourceSocket) {
|
|
837
662
|
sourceSocket.removeAllListeners();
|
|
@@ -840,29 +665,29 @@ var Mercury = _webexCore.WebexPlugin.extend((_dec = (0, _common.deprecated)('Mer
|
|
|
840
665
|
switch (event.code) {
|
|
841
666
|
case 1003:
|
|
842
667
|
// metric: disconnect
|
|
843
|
-
this.logger.info("".concat(this.namespace, ": Mercury service rejected last message
|
|
844
|
-
if (isActiveSocket) this._emit(
|
|
668
|
+
this.logger.info("".concat(this.namespace, ": Mercury service rejected last message; will not reconnect: ").concat(event.reason));
|
|
669
|
+
if (isActiveSocket) this._emit('offline.permanent', event);
|
|
845
670
|
break;
|
|
846
671
|
case 4000:
|
|
847
|
-
// metric: disconnect
|
|
672
|
+
// metric: disconnect, check reason
|
|
848
673
|
if (reason === 'replaced') {
|
|
849
|
-
this._submitMercuryClose4000Metric(
|
|
674
|
+
this._submitMercuryClose4000Metric(event, {
|
|
850
675
|
action: 'no_action',
|
|
851
676
|
isActiveSocket: isActiveSocket,
|
|
852
677
|
messageType: 'replaced'
|
|
853
678
|
});
|
|
854
|
-
this.logger.info("".concat(this.namespace, ": socket
|
|
855
|
-
if (isActiveSocket) this._emit(
|
|
679
|
+
this.logger.info("".concat(this.namespace, ": socket replaced; will not reconnect"));
|
|
680
|
+
if (isActiveSocket) this._emit('offline.replaced', event);
|
|
856
681
|
} else {
|
|
857
|
-
this._submitMercuryClose4000Metric(
|
|
682
|
+
this._submitMercuryClose4000Metric(event, {
|
|
858
683
|
action: isActiveSocket ? 'reconnect' : 'ignore_non_active',
|
|
859
684
|
isActiveSocket: isActiveSocket,
|
|
860
685
|
messageType: 'other'
|
|
861
686
|
});
|
|
862
|
-
this.logger.info("".concat(this.namespace, ": socket
|
|
687
|
+
this.logger.info("".concat(this.namespace, ": socket disconnected with 4000: ").concat(event.reason, "; reconnecting"));
|
|
863
688
|
if (isActiveSocket) {
|
|
864
|
-
this._emit(
|
|
865
|
-
this._reconnect(socketUrl
|
|
689
|
+
this._emit('offline.transient', event);
|
|
690
|
+
this._reconnect(socketUrl);
|
|
866
691
|
}
|
|
867
692
|
}
|
|
868
693
|
break;
|
|
@@ -872,23 +697,23 @@ var Mercury = _webexCore.WebexPlugin.extend((_dec = (0, _common.deprecated)('Mer
|
|
|
872
697
|
// Server closed active socket with 4001, meaning it expected this connection
|
|
873
698
|
// to be replaced, but the switchover in _handleImminentShutdown failed.
|
|
874
699
|
// This is a permanent failure - do not reconnect.
|
|
875
|
-
this.logger.warn("".concat(this.namespace, ": active socket closed with 4001; shutdown switchover failed
|
|
876
|
-
this._emit(
|
|
700
|
+
this.logger.warn("".concat(this.namespace, ": active socket closed with 4001; shutdown switchover failed"));
|
|
701
|
+
this._emit('offline.permanent', event);
|
|
877
702
|
} else {
|
|
878
703
|
// Expected: old socket closed after successful switchover
|
|
879
|
-
this.logger.info("".concat(this.namespace, ": old socket closed with 4001 (replaced during shutdown); no reconnect needed
|
|
880
|
-
this._emit(
|
|
704
|
+
this.logger.info("".concat(this.namespace, ": old socket closed with 4001 (replaced during shutdown); no reconnect needed"));
|
|
705
|
+
this._emit('offline.replaced', event);
|
|
881
706
|
}
|
|
882
707
|
break;
|
|
883
708
|
case 1001:
|
|
884
709
|
case 1005:
|
|
885
710
|
case 1006:
|
|
886
711
|
case 1011:
|
|
887
|
-
this.logger.info("".concat(this.namespace, ": socket
|
|
712
|
+
this.logger.info("".concat(this.namespace, ": socket disconnected; reconnecting"));
|
|
888
713
|
if (isActiveSocket) {
|
|
889
|
-
this._emit(
|
|
890
|
-
this.logger.info("".concat(this.namespace, ": [shutdown] reconnecting active socket to recover
|
|
891
|
-
this._reconnect(socketUrl
|
|
714
|
+
this._emit('offline.transient', event);
|
|
715
|
+
this.logger.info("".concat(this.namespace, ": [shutdown] reconnecting active socket to recover"));
|
|
716
|
+
this._reconnect(socketUrl);
|
|
892
717
|
}
|
|
893
718
|
// metric: disconnect
|
|
894
719
|
// if (code == 1011 && reason !== ping error) metric: unexpected disconnect
|
|
@@ -897,88 +722,85 @@ var Mercury = _webexCore.WebexPlugin.extend((_dec = (0, _common.deprecated)('Mer
|
|
|
897
722
|
case 3050:
|
|
898
723
|
// 3050 indicates logout form of closure, default to old behavior, use config reason defined by consumer to proceed with the permanent block
|
|
899
724
|
if (normalReconnectReasons.includes(reason)) {
|
|
900
|
-
this.logger.info("".concat(this.namespace, ": socket
|
|
725
|
+
this.logger.info("".concat(this.namespace, ": socket disconnected; reconnecting"));
|
|
901
726
|
if (isActiveSocket) {
|
|
902
|
-
this._emit(
|
|
903
|
-
this.logger.info("".concat(this.namespace, ": [shutdown] reconnecting due to normal close
|
|
904
|
-
this._reconnect(socketUrl
|
|
727
|
+
this._emit('offline.transient', event);
|
|
728
|
+
this.logger.info("".concat(this.namespace, ": [shutdown] reconnecting due to normal close"));
|
|
729
|
+
this._reconnect(socketUrl);
|
|
905
730
|
}
|
|
906
731
|
// metric: disconnect
|
|
907
732
|
// if (reason === done forced) metric: force closure
|
|
908
733
|
} else {
|
|
909
|
-
this.logger.info("".concat(this.namespace, ": socket
|
|
910
|
-
if (isActiveSocket) this._emit(
|
|
734
|
+
this.logger.info("".concat(this.namespace, ": socket disconnected; will not reconnect: ").concat(event.reason));
|
|
735
|
+
if (isActiveSocket) this._emit('offline.permanent', event);
|
|
911
736
|
}
|
|
912
737
|
break;
|
|
913
738
|
default:
|
|
914
|
-
this.logger.info("".concat(this.namespace, ": socket
|
|
739
|
+
this.logger.info("".concat(this.namespace, ": socket disconnected unexpectedly; will not reconnect"));
|
|
915
740
|
// unexpected disconnect
|
|
916
|
-
if (isActiveSocket) this._emit(
|
|
741
|
+
if (isActiveSocket) this._emit('offline.permanent', event);
|
|
917
742
|
}
|
|
918
743
|
} catch (error) {
|
|
919
|
-
this.logger.error("".concat(this.namespace, ": error occurred in close handler
|
|
744
|
+
this.logger.error("".concat(this.namespace, ": error occurred in close handler"), error);
|
|
920
745
|
}
|
|
921
746
|
},
|
|
922
|
-
_onmessage: function _onmessage(
|
|
923
|
-
var
|
|
924
|
-
this._setTimeOffset(
|
|
747
|
+
_onmessage: function _onmessage(event) {
|
|
748
|
+
var _this0 = this;
|
|
749
|
+
this._setTimeOffset(event);
|
|
925
750
|
var envelope = event.data;
|
|
926
751
|
if (process.env.ENABLE_MERCURY_LOGGING) {
|
|
927
|
-
this.logger.debug("".concat(this.namespace, ": message envelope
|
|
752
|
+
this.logger.debug("".concat(this.namespace, ": message envelope: "), envelope);
|
|
928
753
|
}
|
|
929
|
-
envelope.sessionId = sessionId;
|
|
930
754
|
|
|
931
755
|
// Handle shutdown message shape: { type: 'shutdown' }
|
|
932
756
|
if (envelope && envelope.type === 'shutdown') {
|
|
933
|
-
this.logger.info("".concat(this.namespace, ": [shutdown] imminent shutdown message received
|
|
934
|
-
this._emit(
|
|
935
|
-
this._handleImminentShutdown(
|
|
757
|
+
this.logger.info("".concat(this.namespace, ": [shutdown] imminent shutdown message received"));
|
|
758
|
+
this._emit('event:mercury_shutdown_imminent', envelope);
|
|
759
|
+
this._handleImminentShutdown();
|
|
936
760
|
return _promise.default.resolve();
|
|
937
761
|
}
|
|
938
|
-
envelope.sessionId = sessionId;
|
|
939
762
|
var data = envelope.data;
|
|
940
|
-
this._applyOverrides(data);
|
|
941
763
|
if (!data || !data.eventType) {
|
|
942
|
-
this._emit(
|
|
764
|
+
this._emit('event', envelope);
|
|
943
765
|
return _promise.default.resolve();
|
|
944
766
|
}
|
|
767
|
+
this._applyOverrides(data);
|
|
945
768
|
return this._getEventHandlers(data.eventType).reduce(function (promise, handler) {
|
|
946
769
|
return promise.then(function () {
|
|
947
770
|
var namespace = handler.namespace,
|
|
948
771
|
name = handler.name;
|
|
949
772
|
return new _promise.default(function (resolve) {
|
|
950
|
-
return resolve((
|
|
773
|
+
return resolve((_this0.webex[namespace] || _this0.webex.internal[namespace])[name](data));
|
|
951
774
|
}).catch(function (reason) {
|
|
952
|
-
return
|
|
775
|
+
return _this0.logger.error("".concat(_this0.namespace, ": error occurred in autowired event handler for ").concat(data.eventType), reason);
|
|
953
776
|
});
|
|
954
777
|
});
|
|
955
778
|
}, _promise.default.resolve()).then(function () {
|
|
956
|
-
|
|
957
|
-
var
|
|
958
|
-
|
|
959
|
-
namespace =
|
|
779
|
+
_this0._emit('event', event.data);
|
|
780
|
+
var _ref3 = data.eventType ? data.eventType.split('.') : [],
|
|
781
|
+
_ref4 = (0, _slicedToArray2.default)(_ref3, 1),
|
|
782
|
+
namespace = _ref4[0];
|
|
960
783
|
if (namespace === data.eventType) {
|
|
961
|
-
|
|
784
|
+
_this0._emit("event:".concat(namespace), envelope);
|
|
962
785
|
} else {
|
|
963
|
-
|
|
964
|
-
|
|
786
|
+
_this0._emit("event:".concat(namespace), envelope);
|
|
787
|
+
_this0._emit("event:".concat(data.eventType), envelope);
|
|
965
788
|
}
|
|
966
789
|
}).catch(function (reason) {
|
|
967
|
-
|
|
790
|
+
_this0.logger.error("".concat(_this0.namespace, ": error occurred processing socket message"), reason);
|
|
968
791
|
});
|
|
969
792
|
},
|
|
970
|
-
_setTimeOffset: function _setTimeOffset(
|
|
793
|
+
_setTimeOffset: function _setTimeOffset(event) {
|
|
971
794
|
var wsWriteTimestamp = event.data.wsWriteTimestamp;
|
|
972
795
|
if (typeof wsWriteTimestamp === 'number' && wsWriteTimestamp > 0) {
|
|
973
796
|
this.mercuryTimeOffset = (0, _now.default)() - wsWriteTimestamp;
|
|
974
797
|
}
|
|
975
798
|
},
|
|
976
799
|
_reconnect: function _reconnect(webSocketUrl) {
|
|
977
|
-
|
|
978
|
-
this.
|
|
979
|
-
return this.connect(webSocketUrl, sessionId);
|
|
800
|
+
this.logger.info("".concat(this.namespace, ": reconnecting"));
|
|
801
|
+
return this.connect(webSocketUrl);
|
|
980
802
|
},
|
|
981
|
-
version: "3.12.0-
|
|
803
|
+
version: "3.12.0-llmrefactor.10"
|
|
982
804
|
}, (0, _applyDecoratedDescriptor2.default)(_obj, "listen", [_dec], (0, _getOwnPropertyDescriptor.default)(_obj, "listen"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "stopListening", [_dec2], (0, _getOwnPropertyDescriptor.default)(_obj, "stopListening"), _obj), _obj));
|
|
983
|
-
var
|
|
805
|
+
var _default = exports.default = Mercury;
|
|
984
806
|
//# sourceMappingURL=mercury.js.map
|