fix: prevent agents from running indefinitely after app quit
Agents kept running after closing AgentCompany because worker processes auto-recreated on exit, retry timers were never cleared, child CLI processes weren't terminated, and orchestration had no quit guards. Changes: - Add isQuitting guards to all orchestration/automation entry points - Track and clear all setTimeout/setInterval timers on quit - Send cancel-run to all active CLI processes before killing worker - Add destroyed flag to prevent worker recreation after intentional destroy - Add quit confirmation dialog: Stop All & Quit / Minimize to Background / Cancel - Bump version to 0.4.96 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
222c80e544
commit
05c57be98f
7 files changed
+190
-19
No files matched your search
@@ -192,6 +192,7 @@ export async function bootstrapApplication({
|
||||
// Re-register timers for scheduled social posts (survives app restart).
|
||||
// Scan all companies for queued browser actions with a future scheduledAt time
|
||||
// and set up setTimeout to dispatch them at the right moment.
|
||||
const scheduledPostTimers = new Set<ReturnType<typeof setTimeout>>();
|
||||
try {
|
||||
const snapshot = db.listSnapshot();
|
||||
for (const company of snapshot.companies) {
|
||||
@@ -203,12 +204,15 @@ export async function bootstrapApplication({
|
||||
if (payload.scheduledAt) {
|
||||
const delay = new Date(payload.scheduledAt).getTime() - Date.now();
|
||||
if (delay > 0) {
|
||||
setTimeout(() => {
|
||||
const browserActions = serviceGraph.getBrowserActionService();
|
||||
const timer = setTimeout(() => {
|
||||
scheduledPostTimers.delete(timer);
|
||||
if (isQuittingRef.current) return;
|
||||
const browserActions = serviceGraph?.getBrowserActionService();
|
||||
if (browserActions) {
|
||||
void browserActions.dispatchBrowserAction(action.id, company.id);
|
||||
}
|
||||
}, delay);
|
||||
scheduledPostTimers.add(timer);
|
||||
log.info(`[bootstrap] Re-registered scheduled post timer: action ${action.id} in ${Math.round(delay / 1000)}s`);
|
||||
}
|
||||
// If delay <= 0, the action is overdue -- normal dispatch cycle will pick it up
|
||||
@@ -221,6 +225,16 @@ export async function bootstrapApplication({
|
||||
log.warn(`[bootstrap] Failed to re-register scheduled post timers: ${error instanceof Error ? error.message : String(error)}`);
|
||||
}
|
||||
|
||||
// Register cleanup for bootstrap-owned resources during quit.
|
||||
// This runs BEFORE service-graph's onBeforeQuit (which is registered later).
|
||||
app.on("before-quit", () => {
|
||||
for (const timer of scheduledPostTimers) {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
scheduledPostTimers.clear();
|
||||
notificationService.destroy();
|
||||
});
|
||||
|
||||
// Show the window immediately so the user sees the app launch without delay.
|
||||
await serviceGraph.getDesktopShellService()?.ensureWindow();
|
||||
serviceGraph.getAppLifecycleService()?.register(hasSingleInstanceLock);
|
||||
|
||||
Reference in new issue
Block a user