webui: improve reconnection delays
- make them a lot more aggressive,
as the user is likely sitting and staring at the screen
- make the numbers rounder (easier to grok)
- add some jitter
diff --git a/webui/src/data.ts b/webui/src/data.ts
index af696dc..327ff89 100644
--- a/webui/src/data.ts
+++ b/webui/src/data.ts
@@ -31,10 +31,9 @@
private eventSource: EventSource | null = null;
private reconnectTimer: number | null = null;
private reconnectAttempt: number = 0;
- // Reconnection timeout delays in milliseconds (runs from 1s to 60s)
+ // Reconnection timeout delays in milliseconds (runs from 100ms to ~15s). Fibonacci-ish.
private readonly reconnectDelaysMs: number[] = [
- 1000, 1500, 2250, 3375, 5062.5, 7593.75, 11390.625, 17085.9375,
- 25628.90625, 38443.359375, 57665.0390625, 60000, 60000
+ 100, 100, 200, 300, 500, 800, 1300, 2100, 3400, 5500, 8900, 14400,
];
// Initial load completion tracking
@@ -174,8 +173,13 @@
this.reconnectTimer = null;
}
- const delayIndex = Math.min(this.reconnectAttempt, this.reconnectDelaysMs.length - 1);
- const delay = this.reconnectDelaysMs[delayIndex];
+ const delayIndex = Math.min(
+ this.reconnectAttempt,
+ this.reconnectDelaysMs.length - 1,
+ );
+ let delay = this.reconnectDelaysMs[delayIndex];
+ // Add jitter: +/- 10% of the delay
+ delay *= 0.9 + Math.random() * 0.2;
console.log(
`Scheduling reconnect in ${delay}ms (attempt ${this.reconnectAttempt + 1})`,
diff --git a/webui/src/web-components/sketch-app-shell.test.ts b/webui/src/web-components/sketch-app-shell.test.ts
index 6c8d468..5180f7e 100644
--- a/webui/src/web-components/sketch-app-shell.test.ts
+++ b/webui/src/web-components/sketch-app-shell.test.ts
@@ -297,20 +297,20 @@
// Wait for initial data to load
await page.waitForTimeout(1000);
- // Simulate connection established by setting the connection status property
+ // Simulate connection established by disabling DataManager connection changes
await component.evaluate(async () => {
const appShell = document.querySelector("sketch-app-shell") as any;
- if (appShell) {
+ if (appShell && appShell.dataManager) {
+ // Prevent DataManager from changing connection status during tests
+ appShell.dataManager.scheduleReconnect = () => {};
+ appShell.dataManager.updateConnectionStatus = () => {};
+ // Set connected status
appShell.connectionStatus = "connected";
appShell.requestUpdate();
- // Force an update cycle to complete
await appShell.updateComplete;
}
});
- // Wait a bit more for the status to update and for any async operations
- await page.waitForTimeout(1000);
-
// Check that the call status component shows IDLE
// The last user/agent message (agent with end_of_turn: true) should make it idle
// even though there are commit and tool messages after it
@@ -397,9 +397,15 @@
expect(isIdleResult.expectedWorking).toBe(true);
// Now test the full component interaction
- await component.evaluate(() => {
+ await component.evaluate(async () => {
const appShell = document.querySelector("sketch-app-shell") as any;
if (appShell) {
+ // Disable DataManager connection status changes that interfere with tests
+ if (appShell.dataManager) {
+ appShell.dataManager.scheduleReconnect = () => {};
+ appShell.dataManager.updateConnectionStatus = () => {};
+ }
+
// Set connection status to connected
appShell.connectionStatus = "connected";
@@ -413,6 +419,7 @@
// The messages are already set from the previous test
// Force a re-render
appShell.requestUpdate();
+ await appShell.updateComplete;
}
});