fix: reconnect SSE immediately on OS wake-from-sleep (#1066)
* fix: reconnect SSE immediately on OS wake-from-sleep When the desktop app resumes from OS sleep, TCP connections are dead but timers were paused during sleep so the heartbeat watchdog doesn't fire until ~30s after wake. Add Electron powerMonitor.resume → renderer notification → event-pipeline immediate abort, cutting reconnection delay from ~30s to ~0ms. Changes: - electron/main.mjs: import powerMonitor, emit openchamber:system-resume to all renderer windows on OS resume - ui/sync/event-pipeline.ts: listen for openchamber:system-resume, set attemptAbortReason and abort the active SSE/WS attempt to trigger immediate reconnection with retryDelayMs=0 and lastEventId preservation * fix: reconnect SSE immediately on OS wake-from-sleep When the desktop app resumes from OS sleep, TCP connections are dead but timers were paused during sleep so the heartbeat watchdog doesn't fire until ~30s after wake. Add Electron powerMonitor.resume → renderer notification → event-pipeline immediate abort, cutting reconnection delay from ~30s to ~0ms. Changes: - electron/main.mjs: import powerMonitor, emit openchamber:system-resume to all renderer windows on OS resume - ui/sync/event-pipeline.ts: listen for openchamber:system-resume via globalThis.window, set attemptAbortReason and abort the active SSE/WS attempt to trigger immediate reconnection with retryDelayMs=0 and lastEventId preservation - Test: event-pipeline-resume.test.js verifies abort → reconnect flow
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { app, BrowserWindow, dialog, ipcMain, Menu, nativeTheme, Notification, session, shell } from 'electron';
|
||||
import { app, BrowserWindow, dialog, ipcMain, Menu, nativeTheme, Notification, powerMonitor, session, shell } from 'electron';
|
||||
import contextMenu from 'electron-context-menu';
|
||||
import log from 'electron-log/main.js';
|
||||
import dgram from 'node:dgram';
|
||||
@@ -2366,6 +2366,12 @@ app.whenReady().then(async () => {
|
||||
const { initialUrl, localOrigin, bootOutcome } = await resolveInitialUrl();
|
||||
await activateMainWindow(initialUrl, localOrigin, bootOutcome);
|
||||
startQuitRiskPoller();
|
||||
|
||||
// Notify renderer on OS wake-from-sleep so the SSE event pipeline can
|
||||
// reconnect immediately instead of waiting for the heartbeat watchdog.
|
||||
powerMonitor.on('resume', () => {
|
||||
emitToAllWindows('openchamber:system-resume', { timestamp: Date.now() });
|
||||
});
|
||||
}).catch((error) => {
|
||||
log.error('[electron] startup failed:', error);
|
||||
app.exit(1);
|
||||
|
||||
Reference in New Issue
Block a user