From b2e20c22b1e1c022bff45fae36281eeb15464886 Mon Sep 17 00:00:00 2001 From: Douwe Osinga Date: Wed, 11 Mar 2026 14:11:32 -0400 Subject: [PATCH] Stop collecting goosed stderr after startup (#7814) Co-authored-by: Douwe Osinga --- ui/desktop/src/goosed.ts | 15 +++++++++++---- ui/desktop/src/main.ts | 13 ++++++++++++- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/ui/desktop/src/goosed.ts b/ui/desktop/src/goosed.ts index 3fb6df24..a5265268 100644 --- a/ui/desktop/src/goosed.ts +++ b/ui/desktop/src/goosed.ts @@ -159,6 +159,7 @@ export interface GoosedResult { workingDir: string; process: ChildProcess | null; errorLog: string[]; + stopErrorLogCollection: () => void; cleanup: () => Promise; client: Client; certFingerprint: string | null; @@ -199,6 +200,7 @@ export const startGoosed = async (options: StartGoosedOptions): Promise {}, cleanup: async () => { logger.info('Not killing external process that is managed externally'); }, @@ -217,6 +219,7 @@ export const startGoosed = async (options: StartGoosedOptions): Promise {}, cleanup: async () => { logger.info('Not killing external process that is managed externally'); }, @@ -300,19 +303,22 @@ export const startGoosed = async (options: StartGoosedOptions): Promise { + const onStderrData = (data: Buffer) => { const lines = data.toString().split('\n'); for (const line of lines) { if (line.trim()) { errorLog.push(line); if (isFatalError(line)) { logger.error(`goosed stderr for port ${port} and dir ${workingDir}: ${line}`); - } else { - logger.info(`goosed stderr for port ${port} and dir ${workingDir}: ${line}`); } } } - }); + }; + goosedProcess.stderr?.on('data', onStderrData); + + const stopErrorLogCollection = () => { + goosedProcess.stderr?.off('data', onStderrData); + }; goosedProcess.on('exit', (code) => { logger.info(`goosed process exited with code ${code} for port ${port} and dir ${workingDir}`); @@ -363,6 +369,7 @@ export const startGoosed = async (options: StartGoosedOptions): Promise { await goosedResult.cleanup(); }); - const { baseUrl, workingDir, process: goosedProcess, errorLog } = goosedResult; + const { + baseUrl, + workingDir, + process: goosedProcess, + errorLog, + stopErrorLogCollection, + } = goosedResult; const mainWindowState = windowStateKeeper({ defaultWidth: 940, @@ -698,6 +704,11 @@ const createChat = async (app: App, options: CreateChatOptions = {}) => { app.quit(); } + // errorLog is only needed during startup to detect fatal errors. + // Stop collecting stderr to avoid unbounded memory growth over long sessions. + stopErrorLogCollection(); + errorLog.length = 0; + // Let windowStateKeeper manage the window mainWindowState.manage(mainWindow);