From e682f466d0c191c8a5ebcb961b5135a76990d9e2 Mon Sep 17 00:00:00 2001 From: fforres Date: Mon, 12 Oct 2026 15:49:14 -0700 Subject: [PATCH] fix(runtime): execute runs for up to sixty minutes by default Raise DEFAULT_TIMEOUT_MS from five to sixty minutes in the dynamic-worker, QuickJS, Deno and workerd runtimes, so a script that waits on a long job finishes in one execute call. Callers can still pass a shorter timeoutMs. Claude-Session: https://claude.ai/code/session_018KRLKV5j8vbaAyH3UgPVtw --- .changeset/execute-one-hour.md | 8 ++++++++ apps/host-selfhost/src/config.ts | 2 +- packages/kernel/runtime-deno-subprocess/src/index.ts | 2 +- packages/kernel/runtime-dynamic-worker/src/executor.ts | 4 ++-- packages/kernel/runtime-quickjs/README.md | 10 +++++----- packages/kernel/runtime-quickjs/src/index.ts | 6 +++--- .../kernel/runtime-workerd-subprocess/src/index.ts | 2 +- 7 files changed, 21 insertions(+), 13 deletions(-) create mode 100644 .changeset/execute-one-hour.md diff --git a/.changeset/execute-one-hour.md b/.changeset/execute-one-hour.md new file mode 100644 index 0000000000..47f4a2ba47 --- /dev/null +++ b/.changeset/execute-one-hour.md @@ -0,0 +1,8 @@ +--- +"@executor-js/runtime-dynamic-worker": patch +"@executor-js/runtime-quickjs": patch +"@executor-js/runtime-deno-subprocess": patch +"@executor-js/runtime-workerd-subprocess": patch +--- + +Code run through `execute` now has sixty minutes by default before it is stopped, up from five, so a script that waits on a long job (polling a machine run, a long upstream call) finishes in one call. A caller can still pass a shorter `timeoutMs`. diff --git a/apps/host-selfhost/src/config.ts b/apps/host-selfhost/src/config.ts index 07dcc56d14..22472154d6 100644 --- a/apps/host-selfhost/src/config.ts +++ b/apps/host-selfhost/src/config.ts @@ -76,7 +76,7 @@ export interface SelfHostConfig { readonly orgSlug: string; /** * Sandbox execution budget passed to the QuickJS runtime, or undefined for - * the runtime's own default (5 minutes). An operator knob in principle, but + * the runtime's own default (60 minutes). An operator knob in principle, but * its real consumer is the e2e harness, which shrinks it to seconds so the * sandbox-deadline scenario proves its race without waiting out real * minutes (the same pattern as MCP_PAUSED_SESSION_IDLE_TIMEOUT_MS on cloud). diff --git a/packages/kernel/runtime-deno-subprocess/src/index.ts b/packages/kernel/runtime-deno-subprocess/src/index.ts index 4a69800f4b..f39bc20772 100644 --- a/packages/kernel/runtime-deno-subprocess/src/index.ts +++ b/packages/kernel/runtime-deno-subprocess/src/index.ts @@ -31,7 +31,7 @@ export type DenoSubprocessExecutorOptions = { }; const IPC_PREFIX = "@@executor-ipc@@"; -const DEFAULT_TIMEOUT_MS = 5 * 60_000; +const DEFAULT_TIMEOUT_MS = 60 * 60_000; // --------------------------------------------------------------------------- // Errors diff --git a/packages/kernel/runtime-dynamic-worker/src/executor.ts b/packages/kernel/runtime-dynamic-worker/src/executor.ts index e03f2aca8c..f3a74980ce 100644 --- a/packages/kernel/runtime-dynamic-worker/src/executor.ts +++ b/packages/kernel/runtime-dynamic-worker/src/executor.ts @@ -44,7 +44,7 @@ export class DynamicWorkerExecutionError extends Data.TaggedError("DynamicWorker export type DynamicWorkerExecutorOptions = { readonly loader: WorkerLoader; /** - * Timeout in milliseconds for code execution. Defaults to 5 minutes. + * Timeout in milliseconds for code execution. Defaults to 60 minutes. */ readonly timeoutMs?: number; /** @@ -103,7 +103,7 @@ type WorkerRpcResponse = WorkerRpcSuccess | WorkerRpcFailure; // Constants // --------------------------------------------------------------------------- -const DEFAULT_TIMEOUT_MS = 5 * 60_000; +const DEFAULT_TIMEOUT_MS = 60 * 60_000; /** * Extra wall-clock the host waits beyond the effective in-sandbox timeout * before declaring the isolate wedged. The in-sandbox timer should always fire diff --git a/packages/kernel/runtime-quickjs/README.md b/packages/kernel/runtime-quickjs/README.md index dca9e26041..0d32a1eca3 100644 --- a/packages/kernel/runtime-quickjs/README.md +++ b/packages/kernel/runtime-quickjs/README.md @@ -33,11 +33,11 @@ const engine = createExecutionEngine({ ### Options -| Option | Default | Description | -| ------------------- | ---------- | --------------------------------- | -| `timeoutMs` | `300_000` | Max wall-clock time per execution | -| `memoryLimitBytes` | `64 * 1MB` | Max memory the VM can allocate | -| `maxStackSizeBytes` | `1 * 1MB` | Max call-stack depth | +| Option | Default | Description | +| ------------------- | ----------- | --------------------------------- | +| `timeoutMs` | `3_600_000` | Max wall-clock time per execution | +| `memoryLimitBytes` | `64 * 1MB` | Max memory the VM can allocate | +| `maxStackSizeBytes` | `1 * 1MB` | Max call-stack depth | ### Swapping the QuickJS build diff --git a/packages/kernel/runtime-quickjs/src/index.ts b/packages/kernel/runtime-quickjs/src/index.ts index 90de8461bf..d8a8e48dd3 100644 --- a/packages/kernel/runtime-quickjs/src/index.ts +++ b/packages/kernel/runtime-quickjs/src/index.ts @@ -57,9 +57,9 @@ class QuickJsExecutionError extends Data.TaggedError("QuickJsExecutionError")<{ readonly message: string; }> {} -// Large OpenAPI specs can take longer to parse inside QuickJS, so keep the -// default execution budget at five minutes unless a caller opts into less. -const DEFAULT_TIMEOUT_MS = 5 * 60_000; +// Long jobs (polling a machine run, parsing a large OpenAPI spec) need room, +// so the default execution budget is sixty minutes unless a caller opts into less. +const DEFAULT_TIMEOUT_MS = 60 * 60_000; const DEFAULT_MEMORY_LIMIT_BYTES = 64 * 1024 * 1024; const DEFAULT_MAX_STACK_SIZE_BYTES = 1 * 1024 * 1024; const EXECUTION_FILENAME = "executor-quickjs-runtime.js"; diff --git a/packages/kernel/runtime-workerd-subprocess/src/index.ts b/packages/kernel/runtime-workerd-subprocess/src/index.ts index 12121549e3..77b6ddc97d 100644 --- a/packages/kernel/runtime-workerd-subprocess/src/index.ts +++ b/packages/kernel/runtime-workerd-subprocess/src/index.ts @@ -24,7 +24,7 @@ import * as Effect from "effect/Effect"; export const WORKERD_VERSION = "1.20260708.1"; -const DEFAULT_TIMEOUT_MS = 5 * 60_000; +const DEFAULT_TIMEOUT_MS = 60 * 60_000; const DEFAULT_HOST_TIMEOUT_GRACE_MS = 30_000; export class WorkerdSubprocessError extends Data.TaggedError("WorkerdSubprocessError")<{ readonly message: string;