From 9dbc3ee573fa134064064ff0232675cabfa24ad0 Mon Sep 17 00:00:00 2001 From: Ammar Date: Mon, 27 Oct 2025 19:04:09 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=A4=96=20fix:=20make=20temp=20directory?= =?UTF-8?q?=20cleanup=20non-blocking=20for=20faster=20stream=20interruptio?= =?UTF-8?q?n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When interrupting a stream (especially on SSH), the UI was delayed by 500ms-2s waiting for the temp directory cleanup to complete. The cleanup involved an SSH 'rm -rf' command that blocked the processingPromise resolution, which delayed the stream-abort event emission. This change makes temp directory cleanup fire-and-forget, so the stream-abort event is emitted immediately after the stream breaks out of the processing loop, providing instant UI feedback. The cleanup is still guaranteed to happen (via void promise), but it no longer blocks the critical path for UI responsiveness. _Generated with `cmux`_ --- src/services/streamManager.ts | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/services/streamManager.ts b/src/services/streamManager.ts index 5a05b9af6..b71ddd03f 100644 --- a/src/services/streamManager.ts +++ b/src/services/streamManager.ts @@ -978,19 +978,22 @@ export class StreamManager extends EventEmitter { streamInfo.partialWriteTimer = undefined; } - // Clean up stream temp directory using runtime + // Clean up stream temp directory using runtime (fire-and-forget) + // Don't block stream completion waiting for directory deletion + // This is especially important for SSH where rm -rf can take 500ms-2s if (streamInfo.runtimeTempDir) { - try { - const result = await streamInfo.runtime.exec(`rm -rf "${streamInfo.runtimeTempDir}"`, { + void streamInfo.runtime + .exec(`rm -rf "${streamInfo.runtimeTempDir}"`, { cwd: "~", timeout: 10, + }) + .then(async (result) => { + await result.exitCode; + log.debug(`Cleaned up temp dir: ${streamInfo.runtimeTempDir}`); + }) + .catch((error) => { + log.error(`Failed to cleanup temp dir ${streamInfo.runtimeTempDir}:`, error); }); - await result.exitCode; // Wait for completion - log.debug(`Cleaned up temp dir: ${streamInfo.runtimeTempDir}`); - } catch (error) { - log.error(`Failed to cleanup temp dir ${streamInfo.runtimeTempDir}:`, error); - // Don't throw - cleanup is best-effort - } } this.workspaceStreams.delete(workspaceId);