From f834f9ec5ecf2621e530d8dadaa5061f6ac3728e Mon Sep 17 00:00:00 2001 From: Kris Zyp Date: Wed, 15 Jul 2026 19:39:05 -0600 Subject: [PATCH] fix(startup): scale the idle-silence timeout for CI, matching the absolute-max ceiling DEFAULT_STARTUP_TIMEOUT_MS (the idle/no-output window) was still a flat 60s regardless of environment, while DEFAULT_STARTUP_MAX_MS (the absolute ceiling) already scales 120s -> 300s under CI. Under contended CI runners (e.g. several Harper instances booting concurrently within one sharded test process, each doing CPU/IO-heavy native module loads), a healthy boot can go quiet for more than 60s between debug-log lines without actually being hung, tripping the idle timer well under the (deliberately larger) absolute ceiling. Apply the same 2.5x ratio already used for DEFAULT_STARTUP_MAX_MS: 60s -> 150s under CI. --- README.md | 4 ++-- src/harperLifecycle.ts | 12 ++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 8c60325..750c2d8 100644 --- a/README.md +++ b/README.md @@ -96,7 +96,7 @@ The Harper binary is resolved in the following order: ```ts interface StartHarperOptions { - startupTimeoutMs?: number; // Idle timeout: max gap between startup output chunks. Default: 60000 or HARPER_INTEGRATION_TEST_STARTUP_TIMEOUT_MS + startupTimeoutMs?: number; // Idle timeout: max gap between startup output chunks. Default: 60000 (150000 under CI) or HARPER_INTEGRATION_TEST_STARTUP_TIMEOUT_MS startupMaxMs?: number; // Absolute startup ceiling regardless of output. Default: 120000 (300000 under CI) or HARPER_INTEGRATION_TEST_STARTUP_MAX_MS config?: object; // Harper config overrides (passed via HARPER_SET_CONFIG) env?: object; // Additional environment variables for the Harper process @@ -110,7 +110,7 @@ Startup readiness is detected by Harper printing `successfully started`. Rather **Environment Variables:** -- `HARPER_INTEGRATION_TEST_STARTUP_TIMEOUT_MS` - Idle startup timeout: max time between chunks of startup output before Harper is treated as hung (resets on output). Default `60000`. +- `HARPER_INTEGRATION_TEST_STARTUP_TIMEOUT_MS` - Idle startup timeout: max time between chunks of startup output before Harper is treated as hung (resets on output). Default `60000` (`150000` under CI). - `HARPER_INTEGRATION_TEST_STARTUP_MAX_MS` - Absolute ceiling on total startup time, regardless of ongoing output. Default `120000` (`300000` under CI). - `HARPER_INTEGRATION_TEST_INSTALL_PARENT_DIR` - Parent directory for temp Harper install dirs (default: OS tmpdir) - `HARPER_INTEGRATION_TEST_INSTALL_SCRIPT` - Path to Harper CLI script diff --git a/src/harperLifecycle.ts b/src/harperLifecycle.ts index 23952bd..0fe4ed2 100644 --- a/src/harperLifecycle.ts +++ b/src/harperLifecycle.ts @@ -59,11 +59,15 @@ const IS_CI = !!process.env.CI; * Maximum time to wait between chunks of Harper startup output before treating the process * as hung. The startup watchdog resets this window on every chunk of output, so the limit is * time-since-last-progress rather than total boot time: a slow-but-healthy boot that keeps - * logging never trips it — only true silence does. + * logging never trips it — only true silence does. Higher under CI, matching + * {@link DEFAULT_STARTUP_MAX_MS}'s CI scaling — shared/contended runners can go quiet between + * log lines for longer without actually being hung (e.g. native module load/RocksDB open + * competing with sibling concurrently-booting Harper instances for CPU). * - * Override with `HARPER_INTEGRATION_TEST_STARTUP_TIMEOUT_MS`. Default 60s. + * Override with `HARPER_INTEGRATION_TEST_STARTUP_TIMEOUT_MS`. Default 60s (150s under CI). */ -export const DEFAULT_STARTUP_TIMEOUT_MS = parseInt(process.env.HARPER_INTEGRATION_TEST_STARTUP_TIMEOUT_MS || '', 10) || 60000; +export const DEFAULT_STARTUP_TIMEOUT_MS = + parseInt(process.env.HARPER_INTEGRATION_TEST_STARTUP_TIMEOUT_MS || '', 10) || (IS_CI ? 150000 : 60000); /** * Absolute ceiling on total startup time, regardless of ongoing output — a generous backstop @@ -117,7 +121,7 @@ export interface StartHarperOptions { /** * Maximum time (ms) to wait between chunks of startup output before treating Harper as hung. * Resets on every chunk of output, so it bounds silence, not total boot time. - * Falls back to {@link DEFAULT_STARTUP_TIMEOUT_MS} (60s). + * Falls back to {@link DEFAULT_STARTUP_TIMEOUT_MS} (60s locally, 150s under CI). */ startupTimeoutMs?: number; /**