mirror of
https://github.com/cpvalente/ontime.git
synced 2026-09-17 03:53:06 +00:00
fix: recover the websocket when a close goes unreported
This commit is contained in:
committed by
Carlos Valente
parent
2436ec2f9a
commit
4c656950f0
@@ -40,6 +40,10 @@ class MockWebSocket {
|
|||||||
this.onclose?.();
|
this.onclose?.();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Simulates a lost connection without an onclose event. */
|
||||||
|
closeSilently() {
|
||||||
|
this.readyState = MockWebSocket.CLOSED;
|
||||||
|
}
|
||||||
open() {
|
open() {
|
||||||
this.readyState = MockWebSocket.OPEN;
|
this.readyState = MockWebSocket.OPEN;
|
||||||
this.onopen?.();
|
this.onopen?.();
|
||||||
@@ -146,6 +150,16 @@ describe('socket connection watchdog', () => {
|
|||||||
expect(MockWebSocket.instances).toHaveLength(2);
|
expect(MockWebSocket.instances).toHaveLength(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('recovers when a close goes unreported', () => {
|
||||||
|
const socket = openConnection();
|
||||||
|
|
||||||
|
// The watchdog is the only recovery path when no close event arrives.
|
||||||
|
socket.closeSilently();
|
||||||
|
|
||||||
|
vi.advanceTimersByTime(watchdogInterval + socketConfig.reconnectBaseInterval * 2);
|
||||||
|
expect(MockWebSocket.instances).toHaveLength(2);
|
||||||
|
});
|
||||||
|
|
||||||
it('ignores events from a socket which has been replaced', () => {
|
it('ignores events from a socket which has been replaced', () => {
|
||||||
const stale = openConnection();
|
const stale = openConnection();
|
||||||
|
|
||||||
|
|||||||
@@ -320,13 +320,9 @@ function registerConnectionAttempt() {
|
|||||||
* while paused, so extended silence is evidence of a dropped connection.
|
* while paused, so extended silence is evidence of a dropped connection.
|
||||||
*/
|
*/
|
||||||
function checkConnection() {
|
function checkConnection() {
|
||||||
if (!websocket) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const silentFor = Date.now() - lastContact;
|
const silentFor = Date.now() - lastContact;
|
||||||
|
|
||||||
if (websocket.readyState === WebSocket.CONNECTING) {
|
if (websocket?.readyState === WebSocket.CONNECTING) {
|
||||||
// A connection attempt can otherwise hang indefinitely.
|
// A connection attempt can otherwise hang indefinitely.
|
||||||
if (silentFor > socketConfig.connectTimeout) {
|
if (silentFor > socketConfig.connectTimeout) {
|
||||||
reconnectNow('WebSocket: connection attempt timed out');
|
reconnectNow('WebSocket: connection attempt timed out');
|
||||||
@@ -334,9 +330,21 @@ function checkConnection() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (websocket.readyState === WebSocket.OPEN && silentFor > socketConfig.silenceTimeout) {
|
if (websocket?.readyState === WebSocket.OPEN) {
|
||||||
|
if (silentFor > socketConfig.silenceTimeout) {
|
||||||
reconnectNow('WebSocket: no data from server, reconnecting');
|
reconnectNow('WebSocket: no data from server, reconnecting');
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The socket is closing, closed or was never created.
|
||||||
|
* Closing schedules its own reconnect, this is what covers us if that did not happen,
|
||||||
|
* so that there is no state the client can settle in without a way out.
|
||||||
|
*/
|
||||||
|
if (!reconnectTimeout) {
|
||||||
|
scheduleReconnect();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function startWatchdog() {
|
function startWatchdog() {
|
||||||
|
|||||||
Reference in New Issue
Block a user