diff --git a/apps/electron-backend/src/app/startup/login-shell-path.spec.ts b/apps/electron-backend/src/app/startup/login-shell-path.spec.ts index 6ac78d8a6..d08d89c8b 100644 --- a/apps/electron-backend/src/app/startup/login-shell-path.spec.ts +++ b/apps/electron-backend/src/app/startup/login-shell-path.spec.ts @@ -90,6 +90,23 @@ describe('login shell PATH', () => { await expect(stuck.waitForLoginShellPath(60_000)).resolves.toBe(false); }); + it('lets waits before the lookup is scheduled share one deadline', async () => { + jest.useFakeTimers(); + try { + const module = loadModule(); + const first = module.waitForLoginShellPath(); + await jest.advanceTimersByTimeAsync(6_000); + const retry = module.waitForLoginShellPath(); + await jest.advanceTimersByTimeAsync(4_000); + // Both end at the first wait's deadline, not 10 s after the retry. + await expect(first).resolves.toBe(false); + await expect(retry).resolves.toBe(false); + await expect(module.waitForLoginShellPath()).resolves.toBe(false); + } finally { + jest.useRealTimers(); + } + }); + it('lets a launch retried within the budget wait for the PATH again', async () => { let resolveShell: (path: string) => void = () => undefined; const module = loadModule(); diff --git a/apps/electron-backend/src/app/startup/login-shell-path.ts b/apps/electron-backend/src/app/startup/login-shell-path.ts index 910d60b21..7cc796eb4 100644 --- a/apps/electron-backend/src/app/startup/login-shell-path.ts +++ b/apps/electron-backend/src/app/startup/login-shell-path.ts @@ -48,7 +48,8 @@ const settledOutcome = loginShellPathSettled.then(() => { /** * Resolves once the login shell PATH lookup has finished (successfully or * not), or when its budget is spent; immediately on Windows. Before the - * lookup is scheduled, a wait lasts at most `limitMs`. Resolves to whether + * lookup is scheduled, waits end at a deadline shared from the first of + * them. `limitMs` caps a single wait. Resolves to whether * the lookup had finished: false means the caller runs on the inherited * PATH and should not keep a negative result. */ @@ -58,10 +59,10 @@ export function waitForLoginShellPath( if (loginShellPathHasSettled) { return Promise.resolve(true); } - const remainingMs = - loginShellPathDeadline === null - ? limitMs - : Math.min(limitMs, loginShellPathDeadline - Date.now()); + // Waits before the lookup is scheduled share one deadline too, set by + // the first of them; scheduling the lookup replaces it with its budget. + loginShellPathDeadline ??= Date.now() + LOGIN_SHELL_PATH_WAIT_LIMIT_MS; + const remainingMs = Math.min(limitMs, loginShellPathDeadline - Date.now()); if (remainingMs <= 0) { return Promise.resolve(false); }