Skip to content

atenet/router: fail fast on FailedPrecondition instead of parking - #3472

Merged
Tim Hockin (thockin) merged 1 commit into
agent-substrate:mainfrom
ygao-g:explore-3269-minimal
Oct 30, 2026
Merged

Tim Hockin (thockin) merged 1 commit into
agent-substrate:mainfrom
ygao-g:explore-3269-minimal

Conversation

@ygao-g

@ygao-g Yuan Gao (ygao-g) commented Oct 29, 2026 •

Copy link
Copy Markdown
Collaborator

A routed request to an actor in ACTOR_STATE_CRASHED parks in atenet-router for the whole 5 s budget, makes about 19 ResumeActor calls, holds one parking slot throughout, and then answers 503. The state never clears on its own, so the wait buys nothing.

Fixes #3269
Part of #1562

retryable in cmd/atenet/internal/router/ingress/resumer.go drops FailedPrecondition from the park arm, so the request fails on the first attempt with the same 503 and the same body. ResourceExhausted and Unavailable still park, Aborted is still always retried, and nothing changes with parking disabled. No ateapi change.

Behavior change: every FailedPrecondition from ResumeActor now fails fast, not only CRASHED. That covers DELETING, SUSPENDING and REVERTING, a missing template, a volume without a storage ID, a worker without a node name, and a failed DetachActor. Two situations behind SUSPENDING and REVERTING:

  • An operation in progress. SuspendActor, RevertActor and DeleteActor hold the actor lease for their whole run, so a resume during one gets Aborted, which still parks. Nothing changes here.
  • A failed operation. A failed suspend/revert that fails at any step, leaves the actor SUSPENDING/REVERTING with no lease held. The resume then gets FailedPrecondition and now fails fast. A retried suspend or revert is what moves the actor on, never the resume retry.

The status code and the body are unchanged.

The e2e TestRoutedRequestToCrashedActorFailsFast crashes an actor by deleting its worker pod and routes one request: 503 naming the state within 2 s, where a parked request would first wait out the 5 s budget. It skips on the AgentGateway lane, whose resume path is outside this repo. docs/concepts/request-parking.md now lists FailedPrecondition under fail fast. Verified with go test -race -count=3 -shuffle=on on the router package, hack/verify-all.sh, and the demo e2e suite on kind.

AI use: AI-assisted under my direction; I reviewed the diff and ran the tests.

  • Tests pass
  • Docs updated

Before this commit, the router parked every FailedPrecondition from
ResumeActor, so a request to a CRASHED or DELETING actor held a parking
slot for the whole 5 s budget before it answered 503.

Now the router no longer parks on FailedPrecondition: every such answer
now fails on the first attempt.

Signed-off-by: Yuan Gao <[email protected]>
@thockin

Tim Hockin (thockin) commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

SUSPENDING is something we will need to fix (post 1.0), I think. If a request comes in to resume an actor which is mid-suspend, we should probably abort the snapshot and resume.

@dberkov

Copy link
Copy Markdown
Collaborator

SUSPENDING is something we will need to fix (post 1.0), I think. If a request comes in to resume an actor which is mid-suspend, we should probably abort the snapshot and resume.

Zoe Zhao (@zoez7) - could you please add it to the list of tasks we might need consider for lifecycle post GA

@thockin
Tim Hockin (thockin) added this pull request to the merge queue Oct 30, 2026
Merged via the queue into agent-substrate:main with commit 542eca1 Oct 30, 2026
13 checks passed
Dmitry Berkovich (dberkov) pushed a commit that referenced this pull request Nov 2, 2026
)

A routed request to an actor in ACTOR_STATE_CRASHED parks in
atenet-router for the whole 5 s budget, makes about 19 `ResumeActor`
calls, holds one parking slot throughout, and then answers 503. The
state never clears on its own, so the wait buys nothing.

Fixes #3269
Part of #1562

`retryable` in `cmd/atenet/internal/router/ingress/resumer.go` drops
`FailedPrecondition` from the park arm, so the request fails on the
first attempt with the same 503 and the same body. `ResourceExhausted`
and `Unavailable` still park, `Aborted` is still always retried, and
nothing changes with parking disabled. No ateapi change.

Behavior change: every `FailedPrecondition` from `ResumeActor` now fails
fast, not only CRASHED. That covers DELETING, SUSPENDING and REVERTING,
a missing template, a volume without a storage ID, a worker without a
node name, and a failed `DetachActor`. Two situations behind SUSPENDING
and REVERTING:

- An operation in progress. `SuspendActor`, `RevertActor` and
`DeleteActor` hold the actor lease for their whole run, so a resume
during one gets `Aborted`, which still parks. Nothing changes here.
- A failed operation. A failed suspend/revert that fails at any step,
leaves the actor SUSPENDING/REVERTING with no lease held. The resume
then gets `FailedPrecondition` and now fails fast. A retried suspend or
revert is what moves the actor on, never the resume retry.

The status code and the body are unchanged.

The e2e `TestRoutedRequestToCrashedActorFailsFast` crashes an actor by
deleting its worker pod and routes one request: 503 naming the state
within 2 s, where a parked request would first wait out the 5 s budget.
It skips on the AgentGateway lane, whose resume path is outside this
repo. `docs/concepts/request-parking.md` now lists `FailedPrecondition`
under fail fast. Verified with `go test -race -count=3 -shuffle=on` on
the router package, `hack/verify-all.sh`, and the demo e2e suite on
kind.

AI use: AI-assisted under my direction; I reviewed the diff and ran the
tests.

- [x] Tests pass
- [x] Docs updated

Signed-off-by: Yuan Gao <[email protected]>
(cherry picked from commit 542eca1)
Signed-off-by: Eitan Yarmush <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

atenet-router treats FailedPrecondition on CRASHED/DELETING actors as retryable, parking every HTTP request for 5s and returning 503

5 participants