From 8e21fb0539bec2fc7bf1eaddb35ccb2f0b341bf5 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Thu, 31 Jul 2025 16:51:40 -0400 Subject: [PATCH] Fix PowerShell terminal suggestion performance by deduplicating concurrent requests (#259051) --- .../src/terminalSuggestMain.ts | 67 ++++++++++++------- 1 file changed, 44 insertions(+), 23 deletions(-) diff --git a/extensions/terminal-suggest/src/terminalSuggestMain.ts b/extensions/terminal-suggest/src/terminalSuggestMain.ts index e99f1d7a4aa..c12904910d7 100644 --- a/extensions/terminal-suggest/src/terminalSuggestMain.ts +++ b/extensions/terminal-suggest/src/terminalSuggestMain.ts @@ -44,6 +44,7 @@ type ShellGlobalsCacheEntry = { type ShellGlobalsCacheEntryWithMeta = ShellGlobalsCacheEntry & { timestamp: number }; const cachedGlobals: Map = new Map(); +const inflightRequests: Map> = new Map(); let pathExecutableCache: PathExecutableCache; const CACHE_KEY = 'terminalSuggestGlobalsCacheV2'; let globalStorageUri: vscode.Uri; @@ -122,30 +123,50 @@ async function fetchAndCacheShellGlobals( remoteAuthority?: string, background?: boolean ): Promise { - try { - let execShellType = shellType; - if (shellType === TerminalShellType.GitBash) { - execShellType = TerminalShellType.Bash; // Git Bash is a bash shell - } - const options: ExecOptionsWithStringEncoding = { encoding: 'utf-8', shell: execShellType, windowsHide: true }; - const mixedCommands: (string | ICompletionResource)[] | undefined = await getShellSpecificGlobals.get(shellType)?.(options, existingCommands); - const normalizedCommands = mixedCommands?.map(command => typeof command === 'string' ? ({ label: command }) : command); - if (machineId) { - const cacheKey = getCacheKey(machineId, remoteAuthority, shellType); - cachedGlobals.set(cacheKey, { - commands: normalizedCommands, - existingCommands: existingCommands ? Array.from(existingCommands) : undefined, - timestamp: Date.now() - }); - await writeGlobalsCache(); - } - return normalizedCommands; - } catch (error) { - if (!background) { - console.error('Error fetching builtin commands:', error); - } - return; + const cacheKey = getCacheKey(machineId ?? 'no-machine-id', remoteAuthority, shellType); + + // Check if there's already an in-flight request for this cache key + const existingRequest = inflightRequests.get(cacheKey); + if (existingRequest) { + // Wait for the existing request to complete rather than spawning a new process + return existingRequest; } + + // Create a new request and store it in the inflight map + const requestPromise = (async () => { + try { + let execShellType = shellType; + if (shellType === TerminalShellType.GitBash) { + execShellType = TerminalShellType.Bash; // Git Bash is a bash shell + } + const options: ExecOptionsWithStringEncoding = { encoding: 'utf-8', shell: execShellType, windowsHide: true }; + const mixedCommands: (string | ICompletionResource)[] | undefined = await getShellSpecificGlobals.get(shellType)?.(options, existingCommands); + const normalizedCommands = mixedCommands?.map(command => typeof command === 'string' ? ({ label: command }) : command); + if (machineId) { + const cacheKey = getCacheKey(machineId, remoteAuthority, shellType); + cachedGlobals.set(cacheKey, { + commands: normalizedCommands, + existingCommands: existingCommands ? Array.from(existingCommands) : undefined, + timestamp: Date.now() + }); + await writeGlobalsCache(); + } + return normalizedCommands; + } catch (error) { + if (!background) { + console.error('Error fetching builtin commands:', error); + } + return; + } finally { + // Always remove the promise from inflight requests when done + inflightRequests.delete(cacheKey); + } + })(); + + // Store the promise in the inflight map + inflightRequests.set(cacheKey, requestPromise); + + return requestPromise; }