keep client reconnecting after outage
This commit is contained in:
@@ -10,6 +10,11 @@ authentication is considered complete.
|
|||||||
|
|
||||||
The client is a Svelte-based control surface distributed as an x86-64 AppImage. It communicates with `trixie-server` through the documented versioned HTTP and authenticated WebSocket interfaces.
|
The client is a Svelte-based control surface distributed as an x86-64 AppImage. It communicates with `trixie-server` through the documented versioned HTTP and authenticated WebSocket interfaces.
|
||||||
|
|
||||||
|
Connection recovery follows the server policy: the first retry is immediate,
|
||||||
|
then retries wait 3, 10, and 15 seconds, followed by an indefinite 30-second
|
||||||
|
interval until the server reconnects. Manual connection checks do not create
|
||||||
|
overlapping retry loops.
|
||||||
|
|
||||||
Implementation has not started. See the parent workspace's `PLAN.md`, `TODO.md`, and `AGENTS.md` before beginning work.
|
Implementation has not started. See the parent workspace's `PLAN.md`, `TODO.md`, and `AGENTS.md` before beginning work.
|
||||||
|
|
||||||
Consumes the versioned contracts from the sibling `trixie-api` repository.
|
Consumes the versioned contracts from the sibling `trixie-api` repository.
|
||||||
|
|||||||
+13
-7
@@ -20,6 +20,7 @@
|
|||||||
let authError = '';
|
let authError = '';
|
||||||
let authBusy = false;
|
let authBusy = false;
|
||||||
let connectionNotice = '';
|
let connectionNotice = '';
|
||||||
|
let connectionCheckRunning = false;
|
||||||
let realtimeState = 'DISCONNECTED';
|
let realtimeState = 'DISCONNECTED';
|
||||||
let realtimeSocket: WebSocket | undefined;
|
let realtimeSocket: WebSocket | undefined;
|
||||||
let activityEvents: Array<{ event_id: string; event_type: string; occurred_at: string }> = [];
|
let activityEvents: Array<{ event_id: string; event_type: string; occurred_at: string }> = [];
|
||||||
@@ -133,13 +134,16 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function checkServer() {
|
async function checkServer() {
|
||||||
|
if (connectionCheckRunning) return;
|
||||||
|
connectionCheckRunning = true;
|
||||||
connectionState = 'CONNECTING';
|
connectionState = 'CONNECTING';
|
||||||
const retryDelays = [0, 3000, 10000, 15000, 30000];
|
let attempt = 0;
|
||||||
for (let attempt = 0; attempt < retryDelays.length; attempt += 1) {
|
while (true) {
|
||||||
if (retryDelays[attempt] > 0) {
|
const delay = attempt === 0 ? 0 : attempt === 1 ? 3000 : attempt === 2 ? 10000 : attempt === 3 ? 15000 : 30000;
|
||||||
|
if (delay > 0) {
|
||||||
connectionState = 'RECONNECTING';
|
connectionState = 'RECONNECTING';
|
||||||
connectionNotice = `Retry ${attempt + 1}/${retryDelays.length} in ${retryDelays[attempt] / 1000}s`;
|
connectionNotice = `Retry ${attempt + 1} in ${delay / 1000}s`;
|
||||||
await new Promise((resolve) => window.setTimeout(resolve, retryDelays[attempt]));
|
await new Promise((resolve) => window.setTimeout(resolve, delay));
|
||||||
} else {
|
} else {
|
||||||
connectionNotice = 'Connecting to server';
|
connectionNotice = 'Connecting to server';
|
||||||
}
|
}
|
||||||
@@ -152,18 +156,20 @@
|
|||||||
serverCompatibility = `Requires client ${info.minimum_client_version}–${info.maximum_client_version}`;
|
serverCompatibility = `Requires client ${info.minimum_client_version}–${info.maximum_client_version}`;
|
||||||
connectionState = 'INCOMPATIBLE';
|
connectionState = 'INCOMPATIBLE';
|
||||||
connectionNotice = 'Client update required';
|
connectionNotice = 'Client update required';
|
||||||
|
connectionCheckRunning = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
serverCompatibility = info.minimum_client_version && info.maximum_client_version ? `${info.minimum_client_version}–${info.maximum_client_version}` : '';
|
serverCompatibility = info.minimum_client_version && info.maximum_client_version ? `${info.minimum_client_version}–${info.maximum_client_version}` : '';
|
||||||
connectionState = 'CONNECTED';
|
connectionState = 'CONNECTED';
|
||||||
connectionNotice = '';
|
connectionNotice = '';
|
||||||
|
connectionCheckRunning = false;
|
||||||
return;
|
return;
|
||||||
} catch {
|
} catch {
|
||||||
|
connectionState = 'SERVER UNAVAILABLE';
|
||||||
connectionNotice = 'Server unavailable';
|
connectionNotice = 'Server unavailable';
|
||||||
}
|
}
|
||||||
|
attempt += 1;
|
||||||
}
|
}
|
||||||
connectionState = 'SERVER UNAVAILABLE';
|
|
||||||
connectionNotice = 'Reconnect attempts exhausted. Test connection to try again.';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function login() {
|
async function login() {
|
||||||
|
|||||||
Reference in New Issue
Block a user