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