diff --git a/.github/workflows/cli-package-validation.yml b/.github/workflows/cli-package-validation.yml index 9fefc67efda..504309e02af 100644 --- a/.github/workflows/cli-package-validation.yml +++ b/.github/workflows/cli-package-validation.yml @@ -327,7 +327,7 @@ jobs: env: NODE_VERSION: ${{ matrix.node }} run: | - echo "The installed tarball failed on Node $NODE_VERSION" >&2 + echo "The installed tarball failed on Node $NODE_VERSION" exit 1 state-root-qualification: diff --git a/packages/runtime-host/src/__tests__/control-endpoint.test.ts b/packages/runtime-host/src/__tests__/control-endpoint.test.ts index db64a95527a..2a22a468474 100644 --- a/packages/runtime-host/src/__tests__/control-endpoint.test.ts +++ b/packages/runtime-host/src/__tests__/control-endpoint.test.ts @@ -126,7 +126,7 @@ describe('runtime host Windows named-pipe ACL failures', () => { '', ); assert.equal(error.code, 'insecure_endpoint_directory'); - assert.match(error.message, /could not confirm .* within 30000ms and refused the endpoint/); + assert.match(error.message, /could not confirm .* within 60000ms and refused the endpoint/); assert.match(error.message, /powershell killed with SIGTERM/); }); diff --git a/packages/runtime-host/src/client/connect-or-spawn.ts b/packages/runtime-host/src/client/connect-or-spawn.ts index 3d99965454e..be409778f8c 100644 --- a/packages/runtime-host/src/client/connect-or-spawn.ts +++ b/packages/runtime-host/src/client/connect-or-spawn.ts @@ -67,7 +67,10 @@ import { } from '../operator/managed-deployment.js'; import { abortable, waitForRuntimeHostReady } from './wait-for-ready.js'; -const DEFAULT_ELECTION_DEADLINE_MS = 45_000; +// Candidate readiness includes the Windows named-pipe ACL helper, whose +// fail-closed ceiling is 60s. Leave enough room for election and connection +// bookkeeping after that helper returns. +const DEFAULT_ELECTION_DEADLINE_MS = 75_000; const DEFAULT_BACKOFF_MIN_MS = 20; const DEFAULT_BACKOFF_MAX_MS = 250; const MIN_CANDIDATE_INTERVAL_MS = 250; diff --git a/packages/runtime-host/src/client/wait-for-ready.ts b/packages/runtime-host/src/client/wait-for-ready.ts index 13ea284c993..44b49d910ef 100644 --- a/packages/runtime-host/src/client/wait-for-ready.ts +++ b/packages/runtime-host/src/client/wait-for-ready.ts @@ -21,7 +21,7 @@ import type { RuntimeHostConnection } from './connection.js'; export async function waitForRuntimeHostReady( connection: Pick, - timeoutMs = 45_000, + timeoutMs = 75_000, signal?: AbortSignal, ): Promise { if (!Number.isSafeInteger(timeoutMs) || timeoutMs <= 0 || timeoutMs > 120_000) { diff --git a/packages/runtime-host/src/control/endpoint.ts b/packages/runtime-host/src/control/endpoint.ts index cbfabe4ea4c..dd4f4f9e6d8 100644 --- a/packages/runtime-host/src/control/endpoint.ts +++ b/packages/runtime-host/src/control/endpoint.ts @@ -34,12 +34,13 @@ const WINDOWS_PIPE_PATH_ENV = 'MAKA_RUNTIME_HOST_PIPE_PATH'; // per-connection check, so the call has to succeed and a timeout has to // refuse the endpoint. That makes the budget a question of how long we are // willing to wait, not how long the work should take. Windows PowerShell 5.1 -// cold start plus .NET type loading is seconds on a loaded CI runner, and a -// 10s budget killed a healthy run (#3225); keep the ceiling well clear of a -// slow start so it only fires on a genuinely stuck process. Endpoint readiness -// waits on this, so raising it means checking that the waiters still outlast -// it: scripts/windows-runtime-host-local-ipc-trust.ps1 and client/wait-for-ready.ts. -const WINDOWS_PIPE_ACL_TIMEOUT_MS = 30_000; +// cold start plus .NET type loading is seconds on a loaded CI runner, and both +// 10s (#3225) and 30s (npm Nightly run 34917337079) budgets have killed healthy +// hosted runners. Keep a full minute so ordinary runner variance does not +// refuse a secure endpoint. Endpoint readiness waits on this, so raising it +// means checking that the waiters still outlast it: +// scripts/windows-runtime-host-local-ipc-trust.ps1 and client/connect-or-spawn.ts. +const WINDOWS_PIPE_ACL_TIMEOUT_MS = 60_000; const WINDOWS_PIPE_ACL_DIAGNOSTIC_LIMIT = 1_000; const WINDOWS_PIPE_ACL_STDERR_MAX_BYTES = 4 * 1024; const WINDOWS_PIPE_ACL_SCRIPT = String.raw` diff --git a/scripts/windows-runtime-host-local-ipc-trust.ps1 b/scripts/windows-runtime-host-local-ipc-trust.ps1 index 7572d251482..228a57597c7 100644 --- a/scripts/windows-runtime-host-local-ipc-trust.ps1 +++ b/scripts/windows-runtime-host-local-ipc-trust.ps1 @@ -158,9 +158,9 @@ try { # The fixture prints readiness only once the endpoint ACL has been applied, so # this deadline has to outlast WINDOWS_PIPE_ACL_TIMEOUT_MS in # packages/runtime-host/src/control/endpoint.ts -- otherwise this throws first - # and the fixture's own diagnostic is never read. 45s matches the client - # readiness budget in packages/runtime-host/src/client/wait-for-ready.ts. - $ready = Read-ProcessLine -Process $fixture -TimeoutMilliseconds 45000 | ConvertFrom-Json + # and the fixture's own diagnostic is never read. 75s matches the client + # election budget in packages/runtime-host/src/client/connect-or-spawn.ts. + $ready = Read-ProcessLine -Process $fixture -TimeoutMilliseconds 75000 | ConvertFrom-Json if ($ready.type -ne 'ready' -or $ready.endpoint -notmatch '^\\\\\.\\pipe\\(.+)$') { throw "Invalid Runtime Host trust fixture readiness: $($ready | ConvertTo-Json -Compress)" }