From 044b66d7e149e15f2b34eba1a23223c929b5298f Mon Sep 17 00:00:00 2001 From: eleanorjboyd <26030610+eleanorjboyd@users.noreply.github.com> Date: Mon, 2 Mar 2026 21:37:45 -0800 Subject: [PATCH] feat: add manager ready timeout setting (exp) --- package.json | 9 +++++++++ package.nls.json | 1 + src/features/common/managerReady.ts | 21 +++++++++++++++++---- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 50317b48..56920487 100644 --- a/package.json +++ b/package.json @@ -135,6 +135,15 @@ "description": "%python-envs.alwaysUseUv.description%", "default": true, "scope": "machine" + }, + "python-envs.experimental.managerReadyTimeout": { + "type": "integer", + "default": 15, + "minimum": 5, + "maximum": 120, + "markdownDescription": "%python-envs.experimental.managerReadyTimeout.description%", + "scope": "machine", + "tags": ["experimental"] } } }, diff --git a/package.nls.json b/package.nls.json index 3a4ddcec..ede6dd57 100644 --- a/package.nls.json +++ b/package.nls.json @@ -13,6 +13,7 @@ "python-envs.terminal.useEnvFile.description": "Controls whether environment variables from .env files and python.envFile setting are injected into terminals.", "python-envs.globalSearchPaths.description": "Absolute paths to search for Python environments across all workspaces. Use for shared environment folders like `~/envs`.", "python-envs.workspaceSearchPaths.description": "Paths to search for environments in this workspace. By default, searches for a `.venv` folder in the workspace root.", + "python-envs.experimental.managerReadyTimeout.description": "(Experimental) Timeout in seconds before giving up on waiting for an environment manager to register. Increase if you use slow or remote filesystems. Default: 15.", "python-envs.terminal.revertStartupScriptChanges.title": "Revert Shell Startup Script Changes", "python-envs.reportIssue.title": "Report Issue", "python-envs.setEnvManager.title": "Set Environment Manager", diff --git a/src/features/common/managerReady.ts b/src/features/common/managerReady.ts index c85b3134..ea28e6f7 100644 --- a/src/features/common/managerReady.ts +++ b/src/features/common/managerReady.ts @@ -7,10 +7,20 @@ import { sendTelemetryEvent } from '../../common/telemetry/sender'; import { createDeferred, Deferred } from '../../common/utils/deferred'; import { showErrorMessage } from '../../common/window.apis'; import { installExtension } from '../../common/workbenchCommands'; +import { getConfiguration } from '../../common/workspace.apis'; import { EnvironmentManagers, PythonProjectManager } from '../../internal.api'; import { getDefaultEnvManagerSetting, getDefaultPkgManagerSetting } from '../settings/settingHelpers'; -const MANAGER_READY_TIMEOUT_MS = 30_000; +const DEFAULT_MANAGER_READY_TIMEOUT_MS = 15_000; + +function getManagerReadyTimeoutMs(): number { + const config = getConfiguration('python-envs'); + const userValue = config.get('experimental.managerReadyTimeout'); + if (typeof userValue === 'number' && userValue >= 5 && userValue <= 120) { + return userValue * 1000; + } + return DEFAULT_MANAGER_READY_TIMEOUT_MS; +} interface ManagerReady extends Disposable { waitForEnvManager(uris?: Uri[]): Promise; @@ -120,13 +130,16 @@ class ManagerReadyImpl implements ManagerReady { if (deferred.completed) { return deferred.promise; } + const timeoutMs = getManagerReadyTimeoutMs(); return new Promise((resolve) => { const timer = setTimeout(() => { if (!deferred.completed) { traceWarn( - `Timed out after ${MANAGER_READY_TIMEOUT_MS / 1000}s waiting for ${kind} manager "${managerId}" to register. ` + + `Timed out after ${timeoutMs / 1000}s waiting for ${kind} manager "${managerId}" to register. ` + `The manager may not be installed or its extension failed to activate. Proceeding without it. ` + - `To prevent this, check your "python-envs.defaultEnvManager" and "python-envs.pythonProjects" settings.`, + `To prevent this, check your "python-envs.defaultEnvManager" and "python-envs.pythonProjects" settings. ` + + `If the manager is slow to start (e.g. on a remote or network filesystem), increase the timeout via ` + + `"python-envs.experimental.managerReadyTimeout" (current: ${timeoutMs / 1000}s, range: 5–120s).`, ); sendTelemetryEvent(EventNames.MANAGER_READY_TIMEOUT, undefined, { managerId, @@ -134,7 +147,7 @@ class ManagerReadyImpl implements ManagerReady { }); deferred.resolve(); } - }, MANAGER_READY_TIMEOUT_MS); + }, timeoutMs); deferred.promise.then( () => {