@wireapp/api-client 27.94.4 → 27.94.5
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.
|
@@ -34,6 +34,7 @@ export declare class ReconnectingWebsocket {
|
|
|
34
34
|
private readonly stopBackFromSleepHandler?;
|
|
35
35
|
private isPingingEnabled;
|
|
36
36
|
private readonly pendingHealthChecks;
|
|
37
|
+
private lastMessageTimestamp;
|
|
37
38
|
constructor(onReconnect: () => Promise<string>, options?: {
|
|
38
39
|
pingInterval?: number;
|
|
39
40
|
});
|
|
@@ -49,7 +50,16 @@ export declare class ReconnectingWebsocket {
|
|
|
49
50
|
send(message: any): void;
|
|
50
51
|
getState(): WEBSOCKET_STATE;
|
|
51
52
|
/**
|
|
52
|
-
* Lightweight health probe that
|
|
53
|
+
* Lightweight health probe that intelligently determines connection health.
|
|
54
|
+
*
|
|
55
|
+
* If the WebSocket is actively processing messages (i.e., received a message within the last 5 seconds),
|
|
56
|
+
* it considers the connection healthy without sending a ping, as message processing
|
|
57
|
+
* indicates the connection is working properly.
|
|
58
|
+
*
|
|
59
|
+
* If the WebSocket is idle, it sends a ping and expects a pong within the timeout.
|
|
60
|
+
* This approach prevents false failures during high-load scenarios where pong responses
|
|
61
|
+
* get queued behind many other messages.
|
|
62
|
+
*
|
|
53
63
|
* Does not close or reconnect the socket; callers can decide how to react to failures.
|
|
54
64
|
*/
|
|
55
65
|
checkHealth(timeoutMs?: number): Promise<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReconnectingWebsocket.d.ts","sourceRoot":"","sources":["../../src/tcp/ReconnectingWebsocket.ts"],"names":[],"mappings":"AAoBA,OAAY,EAAC,UAAU,EAAE,UAAU,EAAE,KAAK,EAAU,MAAM,wBAAwB,CAAC;AAQnF,oBAAY,cAAc;IACxB,cAAc,OAAO;IACrB,UAAU,OAAO;IACjB,cAAc,OAAO;IACrB,gBAAgB,OAAO;CACxB;AAED,oBAAY,eAAe;IACzB,UAAU,IAAI;IACd,IAAI,IAAI;IACR,OAAO,IAAI;IACX,MAAM,IAAI;CACX;AAED,oBAAY,WAAW;IACrB,IAAI,SAAS;IACb,IAAI,SAAS;CACd;AAED,qBAAa,qBAAqB;
|
|
1
|
+
{"version":3,"file":"ReconnectingWebsocket.d.ts","sourceRoot":"","sources":["../../src/tcp/ReconnectingWebsocket.ts"],"names":[],"mappings":"AAoBA,OAAY,EAAC,UAAU,EAAE,UAAU,EAAE,KAAK,EAAU,MAAM,wBAAwB,CAAC;AAQnF,oBAAY,cAAc;IACxB,cAAc,OAAO;IACrB,UAAU,OAAO;IACjB,cAAc,OAAO;IACrB,gBAAgB,OAAO;CACxB;AAED,oBAAY,eAAe;IACzB,UAAU,IAAI;IACd,IAAI,IAAI;IACR,OAAO,IAAI;IACX,MAAM,IAAI;CACX;AAED,oBAAY,WAAW;IACrB,IAAI,SAAS;IACb,IAAI,SAAS;CACd;AAED,qBAAa,qBAAqB;IA+B9B,OAAO,CAAC,QAAQ,CAAC,WAAW;IA9B9B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,oBAAoB,CAQ1C;IAEF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,MAAM,CAAC,CAAM;IACrB,OAAO,CAAC,QAAQ,CAAC,CAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAqC;IACnE,OAAO,CAAC,iBAAiB,CAAU;IACnC,OAAO,CAAC,MAAM,CAAC,CAAyB;IACxC,OAAO,CAAC,SAAS,CAAC,CAAyB;IAC3C,OAAO,CAAC,OAAO,CAAC,CAA8B;IAC9C,OAAO,CAAC,OAAO,CAAC,CAA8B;IAC9C;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAC,CAAa;IAEvD,OAAO,CAAC,gBAAgB,CAAQ;IAChC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAA2C;IAC/E,OAAO,CAAC,oBAAoB,CAAK;gBAGd,WAAW,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,EACnD,OAAO,GAAE;QACP,YAAY,CAAC,EAAE,MAAM,CAAC;KAClB;IA+BR,OAAO,CAAC,QAAQ,CAAC,eAAe,CAK9B;IAEF,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAehC;IAEF,OAAO,CAAC,QAAQ,CAAC,cAAc,CAQ7B;IAEF,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAQlC;IAEF,OAAO,CAAC,QAAQ,CAAC,eAAe,CAO9B;IAEF,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAgBvB;IAEK,OAAO,IAAI,IAAI;IAQf,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;IAIxB,QAAQ,IAAI,eAAe;IAIlC;;;;;;;;;;;;OAYG;IACI,WAAW,CAAC,SAAS,SAAoC,GAAG,OAAO,CAAC,OAAO,CAAC;IAmC5E,UAAU,CAAC,MAAM,SAAqB,GAAG,IAAI;IASpD;;;;;;;OAOG;IACH,OAAO,CAAC,OAAO;IAMf,OAAO,CAAC,wBAAwB;IAIhC,OAAO,CAAC,0BAA0B;IAK3B,SAAS,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI;IAI/C,YAAY,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAIrD,UAAU,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,GAAG,IAAI;IAItD,UAAU,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,GAAG,IAAI;IAItD,cAAc,IAAI,IAAI;CAI9B"}
|
|
@@ -96,6 +96,7 @@ class ReconnectingWebsocket {
|
|
|
96
96
|
stopBackFromSleepHandler;
|
|
97
97
|
isPingingEnabled = true;
|
|
98
98
|
pendingHealthChecks = new Set();
|
|
99
|
+
lastMessageTimestamp = 0;
|
|
99
100
|
constructor(onReconnect, options = {}) {
|
|
100
101
|
this.onReconnect = onReconnect;
|
|
101
102
|
this.logger = commons_1.LogFactory.getLogger('@wireapp/api-client/tcp/ReconnectingWebsocket');
|
|
@@ -139,6 +140,7 @@ class ReconnectingWebsocket {
|
|
|
139
140
|
this.resolvePendingHealthChecks(true);
|
|
140
141
|
return;
|
|
141
142
|
}
|
|
143
|
+
this.lastMessageTimestamp = Date.now();
|
|
142
144
|
this.onMessage?.(data);
|
|
143
145
|
};
|
|
144
146
|
internalOnOpen = (event) => {
|
|
@@ -207,16 +209,34 @@ class ReconnectingWebsocket {
|
|
|
207
209
|
return this.socket ? this.socket.readyState : WEBSOCKET_STATE.CLOSED;
|
|
208
210
|
}
|
|
209
211
|
/**
|
|
210
|
-
* Lightweight health probe that
|
|
212
|
+
* Lightweight health probe that intelligently determines connection health.
|
|
213
|
+
*
|
|
214
|
+
* If the WebSocket is actively processing messages (i.e., received a message within the last 5 seconds),
|
|
215
|
+
* it considers the connection healthy without sending a ping, as message processing
|
|
216
|
+
* indicates the connection is working properly.
|
|
217
|
+
*
|
|
218
|
+
* If the WebSocket is idle, it sends a ping and expects a pong within the timeout.
|
|
219
|
+
* This approach prevents false failures during high-load scenarios where pong responses
|
|
220
|
+
* get queued behind many other messages.
|
|
221
|
+
*
|
|
211
222
|
* Does not close or reconnect the socket; callers can decide how to react to failures.
|
|
212
223
|
*/
|
|
213
|
-
checkHealth(timeoutMs = commons_1.TimeUtil.TimeInMillis.SECOND *
|
|
224
|
+
checkHealth(timeoutMs = commons_1.TimeUtil.TimeInMillis.SECOND * 10) {
|
|
214
225
|
if (!this.socket || this.getState() !== WEBSOCKET_STATE.OPEN) {
|
|
215
226
|
return Promise.resolve(false);
|
|
216
227
|
}
|
|
228
|
+
const now = Date.now();
|
|
229
|
+
const timeSinceLastMessage = now - this.lastMessageTimestamp;
|
|
230
|
+
// If we're actively processing messages during the last 5 seconds, consider the connection healthy
|
|
231
|
+
if (timeSinceLastMessage < commons_1.TimeUtil.TimeInMillis.SECOND * 5) {
|
|
232
|
+
this.logger.debug(`WebSocket is actively processing messages (last: ${timeSinceLastMessage}ms ago), considering healthy`);
|
|
233
|
+
return Promise.resolve(true);
|
|
234
|
+
}
|
|
235
|
+
// If idle, use ping/pong to verify connection
|
|
217
236
|
return new Promise(resolve => {
|
|
218
237
|
const timeoutId = setTimeout(() => {
|
|
219
238
|
this.pendingHealthChecks.delete(resolveHealthCheck);
|
|
239
|
+
this.logger.debug('Health check timeout - no pong received within timeout');
|
|
220
240
|
resolve(false);
|
|
221
241
|
}, timeoutMs);
|
|
222
242
|
const resolveHealthCheck = (isHealthy) => {
|
|
@@ -224,6 +244,7 @@ class ReconnectingWebsocket {
|
|
|
224
244
|
resolve(isHealthy);
|
|
225
245
|
};
|
|
226
246
|
this.pendingHealthChecks.add(resolveHealthCheck);
|
|
247
|
+
this.logger.debug('WebSocket is idle, sending ping for health check');
|
|
227
248
|
this.send(PingMessage.PING);
|
|
228
249
|
});
|
|
229
250
|
}
|
package/package.json
CHANGED