perf: reduce desktop quit risk polling

Refresh quit risk only when quitting
Use in-process status for Electron local server
Avoid repeated scheduled task status scans
This commit is contained in:
Bohdan Triapitsyn
2026-04-30 13:54:58 +03:00
parent bbd83d60c6
commit 8152bd7808
4 changed files with 50 additions and 21 deletions
+20 -21
View File
@@ -128,7 +128,6 @@ const state = {
quitConfirmed: false,
quitConfirmationPending: false,
installingUpdate: false,
quitRiskPollerStarted: false,
pendingUpdate: null,
unreachableHosts: new Set(),
windowCounter: 1,
@@ -138,7 +137,6 @@ const state = {
sshLogs: new Map(),
};
const QUIT_RISK_POLL_INTERVAL_MS = 5_000;
const quitRisk = {
hasActiveTunnel: false,
hasRunningScheduledTasks: false,
@@ -206,6 +204,8 @@ const performConfirmedQuit = () => {
};
const requestQuitWithConfirmation = async () => {
await refreshQuitRiskFlags();
if (!shouldRequireQuitConfirmation()) {
performConfirmedQuit();
return;
@@ -247,6 +247,24 @@ const requestQuitWithConfirmation = async () => {
};
const refreshQuitRiskFlags = async () => {
if (state.serverHandle && typeof state.serverHandle.getQuitRiskStatus === 'function') {
try {
const status = await state.serverHandle.getQuitRiskStatus();
const scheduled = status?.scheduledTasks;
if (scheduled && typeof scheduled === 'object') {
const enabledCount = Number(scheduled.enabledScheduledTasksCount ?? 0);
const runningCount = Number(scheduled.runningScheduledTasksCount ?? 0);
quitRisk.enabledScheduledTasksCount = Number.isFinite(enabledCount) ? enabledCount : 0;
quitRisk.runningScheduledTasksCount = Number.isFinite(runningCount) ? runningCount : 0;
quitRisk.hasEnabledScheduledTasks = Boolean(scheduled.hasEnabledScheduledTasks) || quitRisk.enabledScheduledTasksCount > 0;
quitRisk.hasRunningScheduledTasks = Boolean(scheduled.hasRunningScheduledTasks) || quitRisk.runningScheduledTasksCount > 0;
}
quitRisk.hasActiveTunnel = Boolean(status?.tunnel?.active);
return;
} catch {
}
}
const base = typeof state.sidecarUrl === 'string' ? state.sidecarUrl.trim().replace(/\/$/, '') : '';
if (!base) return;
@@ -279,24 +297,6 @@ const refreshQuitRiskFlags = async () => {
}
};
const startQuitRiskPoller = () => {
if (process.platform !== 'darwin') return;
if (state.quitRiskPollerStarted) return;
state.quitRiskPollerStarted = true;
const loop = async () => {
while (!state.quitConfirmed && !state.quitRequested) {
await refreshQuitRiskFlags();
if (state.quitConfirmed || state.quitRequested) break;
await new Promise((resolve) => {
const timer = setTimeout(resolve, QUIT_RISK_POLL_INTERVAL_MS);
if (typeof timer?.unref === 'function') timer.unref();
});
}
};
void loop();
};
const settingsFilePath = () => {
if (typeof process.env.OPENCHAMBER_DATA_DIR === 'string' && process.env.OPENCHAMBER_DATA_DIR.trim()) {
return path.join(process.env.OPENCHAMBER_DATA_DIR.trim(), 'settings.json');
@@ -2399,7 +2399,6 @@ 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.
+6
View File
@@ -1233,6 +1233,12 @@ async function main(options = {}) {
getPort: () => tunnelRuntimeContext.getActivePort(),
getOpenCodePort: () => openCodePort,
getTunnelUrl: () => tunnelService.getPublicUrl(),
getQuitRiskStatus: () => ({
tunnel: {
active: Boolean(tunnelService.getPublicUrl()),
},
scheduledTasks: scheduledTasksRuntime.getStatus(),
}),
isReady: () => isOpenCodeReady,
restartOpenCode: () => restartOpenCode(),
stop: (shutdownOptions = {}) =>
@@ -156,6 +156,10 @@ export const registerScheduledTaskRoutes = (app, dependencies) => {
app.get('/api/openchamber/scheduled-tasks/status', async (_req, res) => {
try {
if (typeof scheduledTasksRuntime.getStatus === 'function') {
return res.json(scheduledTasksRuntime.getStatus());
}
const settings = await readSettingsFromDiskMigrated();
const projects = sanitizeProjects(settings?.projects || []);
@@ -739,11 +739,31 @@ export const createScheduledTasksRuntime = (deps) => {
queue.length = 0;
};
const getStatus = () => {
let enabledCount = 0;
for (const taskMap of tasksByProject.values()) {
for (const task of taskMap.values()) {
if (task?.enabled) {
enabledCount += 1;
}
}
}
const runningCount = runningTaskKeys.size;
return {
hasEnabledScheduledTasks: enabledCount > 0,
hasRunningScheduledTasks: runningCount > 0,
enabledScheduledTasksCount: enabledCount,
runningScheduledTasksCount: runningCount,
};
};
return {
start,
stop,
syncAllProjects,
syncProject,
runNow,
getStatus,
};
};