feat: Configurable timeouts + warmup for long-running / large-snapshot actors#487
Open
Maya Wang (mayawang) wants to merge 1 commit into
Open
feat: Configurable timeouts + warmup for long-running / large-snapshot actors#487Maya Wang (mayawang) wants to merge 1 commit into
Maya Wang (mayawang) wants to merge 1 commit into
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
Maya Wang (mayawang)
force-pushed
the
feat/long-running-actor-support
branch
2 times, most recently
from
July 21, 2026 23:13
15dfc5d to
62b205b
Compare
…t actors
Running a heavy suspend/resume workload (a multi-process Node.js agent) end to
end surfaced four control-plane assumptions that are too tight for actors with
slow initialization or large gVisor snapshots. Each is made tunable (or
opt-out); all defaults are unchanged, so this is purely additive.
- atecontroller: golden-snapshot warmup is env-configurable via
ATE_GOLDEN_WARMUP_SECONDS (default 20s, unchanged). A probe-less workload that
keeps initializing past 20s otherwise gets checkpointed before it is ready,
capturing a dead golden.
- atenet: resume / route / ext_proc timeouts are env-configurable via
ATE_RESUME_TIMEOUT_SECONDS / ATE_ROUTE_TIMEOUT_SECONDS /
ATE_EXTPROC_TIMEOUT_SECONDS (defaults 15s / 10s / 5s, unchanged; see
timeouts.go). Cold restore-on-demand of a large snapshot (tens of MiB) can
take tens of seconds and the default ceilings cancel the in-flight restore,
surfacing as a 504. Long LLM turns likewise exceed the 10s route timeout.
- ateom-gvisor: `runsc start -allow-connected-on-save` is gated behind
ATEOM_RUNSC_ALLOW_CONNECTED_ON_SAVE (default true, unchanged). Some
GKE-Sandbox runsc builds do not define the flag and reject `runsc start`
("flag provided but not defined"); this lets those builds opt out.
The atenet timeout bumps are stopgaps for the connected-socket suspend/restore
problem tracked in #465 (suspend-safe actor networking), which should remove
most of the need to tune them.
Maya Wang (mayawang)
force-pushed
the
feat/long-running-actor-support
branch
from
July 22, 2026 03:51
62b205b to
a72632b
Compare
Collaborator
|
Maya Wang (@mayawang) - I have recently added substrate/internal/readyz/readyz.go Line 42 in 0f6144e Have you considered to extend the readyz with a timeout via actorTemplate and push it up to the atelet? |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Makes four control-plane parameters configurable (three new env-var knobs) plus
one opt-out, so that heavy, slow-initializing, or large-snapshot actors can
run end-to-end on Substrate.
No default value is changed. This PR is purely additive — behavior is
identical to today unless an operator sets one of the new environment variables.
Why (context)
This comes out of the OpenClaw-on-Substrate integration: an always-on
conversational agent (a multi-process Node.js workload that holds channel
connections — WhatsApp, etc. — and suspends/resumes per conversation). Running
it end-to-end surfaced four places where the current defaults, which are sized
for lightweight, fast-starting actors, are too tight for this class of workload:
finished initializing → the golden captures a not-ready process.
seconds and is cancelled by the resume / route / ext_proc timeouts → 504.
runsc start -allow-connected-on-saveis rejected by some runsc builds.Rather than change any default, each is made tunable so operators running such
workloads can opt in; everyone else is unaffected.
No defaults changed
20sATE_GOLDEN_WARMUP_SECONDS15sATE_RESUME_TIMEOUT_SECONDS10sATE_ROUTE_TIMEOUT_SECONDS5sATE_EXTPROC_TIMEOUT_SECONDSrunsc start -allow-connected-on-saveATEOM_RUNSC_ALLOW_CONNECTED_ON_SAVE=falseto disableAn unset or invalid env value falls back to the default in every case.
Changes
cmd/atecontroller/.../actortemplate_controller.go— configurable golden warmupFor templates without a
readyzprobe, the controller waits a fixed20safterbooting the golden, then checkpoints. A workload with long, probe-less
initialization is still starting up at 20s, so the checkpoint captures a
not-ready golden. Adds
ATE_GOLDEN_WARMUP_SECONDS(viadefaultGoldenWarmup());default
20sunchanged. Templates that declarereadyzare unaffected (theyalready skip the fixed wait).
cmd/atenet/internal/router/timeouts.go(new) — shared, documented knobsCentralizes the three atenet timeouts, their defaults, and a whole-seconds env
parser in one place, so the
resumer.go/xds.godiffs stay minimal and therationale + defaults live together.
cmd/atenet/internal/router/resumer.go— configurable background resume timeoutThe detached background resume context (
15s) is cancelled before a large coldrestore completes, surfacing as a 504 to the caller. Now
resumeTimeout()(
ATE_RESUME_TIMEOUT_SECONDS, default15s).cmd/atenet/internal/router/xds.go— configurable route + ext_proc timeouts10s): a long agent turn (e.g. an LLM streaming a response)exceeds it and is cut off mid-turn. Now
routeTimeout()(
ATE_ROUTE_TIMEOUT_SECONDS, default10s).5s, bothGrpcService.TimeoutandMessageTimeout):the ext_proc round-trip can drive a cold restore that takes tens of seconds;
5saborts it. NowextProcTimeout()(ATE_EXTPROC_TIMEOUT_SECONDS, default5s).cmd/ateom-gvisor/runsc.go— gate-allow-connected-on-saveThe flag lets
runsccheckpoint a sandbox with open connected sockets, but somerunsc builds (certain GKE-Sandbox releases) do not define it and reject
runsc startwithflag provided but not defined. ExtractedallowConnectedOnSave()(default true, preserving current behavior); setATEOM_RUNSC_ALLOW_CONNECTED_ON_SAVE=falsefor builds that don't support it.Relationship to #465
The atenet timeout bumps are stopgaps for the connected-socket suspend/restore
problem tracked in #465 (suspend-safe actor networking). Once actor network
traffic survives checkpoint/restore natively, most of the need to raise these
ceilings should go away — this PR just makes the current behavior tunable in the
meantime.
Verification & testing
go build ./cmd/atenet/... ./cmd/atecontroller/... ./cmd/ateom-gvisor/...— passes.go vet ./cmd/atenet/internal/router/— clean.ate.dev): a heavyOpenClaw actor (~60 MiB golden) validated through the full lifecycle — golden
capture with an extended warmup (
ATE_GOLDEN_WARMUP_SECONDS=120) reachingReadywith a live snapshot; resume-on-demand (~18s cold / ~9s warm); longLLM turns; gateway-driven suspend; and repeated suspend/resume cycles with live
WhatsApp round-trips.
Honest caveats on the e2e run:
ATE_GOLDEN_WARMUP_SECONDS) was exercised as shipped.values (
120s/300s/60s); this PR refactors those exact values behindenv vars with the defaults unchanged. The refactor is build- and
vet-verified; the env-read path is a straightforward whole-seconds parse with
fallback.
(
ATEOM_RUNSC_ALLOW_CONNECTED_ON_SAVE=false) on a GKE-Sandbox runsc build thatrejects the flag. The default (enabled) path is the pre-existing upstream
behavior and is unchanged.
Out of scope (intentionally excluded)
The gVisor
SandboxConfigchange that pointsrunsc.urlat a specific build isnot included — it is environment-specific (a private bucket + build SHA) and
does not belong upstream. The only generic, upstreamable finding is that a runsc
build which survives a heavy multi-process actor is required; the flag gate above
is the portable part of that.
Fixes #<issue_number_goes_here>