Skip to content

atelet: Answer a retried Checkpoint from the snapshot it committed - #2849

Draft
Michelle Au (msau42) wants to merge 2 commits into
agent-substrate:mainfrom
msau42:checkpoint-retry-committed
Draft

Michelle Au (msau42) wants to merge 2 commits into
agent-substrate:mainfrom
msau42:checkpoint-retry-committed

Conversation

@msau42

@msau42 Michelle Au (msau42) commented Oct 18, 2026 •

Copy link
Copy Markdown
Collaborator

When ateapi loses a Checkpoint's response, it retries with the same snapshot. atelet ran the retry from the start, so it checkpointed the worker again, which fails once the first attempt has deleted the workload. ateapi crashed the actor on that error, and the revert threw away the generation atelet had committed.

A Checkpoint of a snapshot that atelet has already committed now returns the actor's state without checkpointing again. It still uploads the snapshot first if the retry asks for an immediate upload that the first attempt deferred, and, unless the actor has started again since, finishes any cleanup the first attempt left undone. A retry that arrives while the first attempt is still running waits for it, as do Run and Restore. If atelet has already uploaded and detached an async suspend's snapshot, ateapi records it without node locality.

Part of #2069 and #2571

  • Tests pass
  • Appropriate changes to documentation are included in the PR

@msau42

Michelle Au (msau42) commented Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator Author

I'm exploring if there's ways to simplify this. It's getting a bit complex trying to keep tracking of ongoing RPCs and I'm exploring a few things:

  • Leveraging actorLocks to serialize the RPCs
  • Having Terminate wait for other rpcs to complete instead of trying to interrupt/cancel in-progress RPCs

Atelet now runs at most one lifecycle RPC per actor at a time. Run,
Restore, Checkpoint, PromoteSnapshot, DetachActor, and Terminate wait
their turn for the actor.

Before, Terminate could forget an actor and delete its local snapshots
and directories while a Checkpoint or Restore of the actor was still
using them, and a Checkpoint that committed afterward recreated snapshot
state for the terminated actor.

Terminate waits for any in-flight RPC for that actor to finish before
forgetting its snapshot state and removing its local snapshots and actor
directories. With RPCs serialized at the atelet boundary, snapshottracker
only coordinates background uploads, detaches, and reports against the
active RPC.
When ateapi loses a Checkpoint's response, it retries with the same
snapshot. atelet ran the retry from the start, so it checkpointed the
worker again, which fails once the first attempt has deleted the
workload. ateapi crashed the actor on that error, and the revert threw
away the generation atelet had committed.

A Checkpoint of a snapshot that atelet has already committed now
returns the actor's state without checkpointing again. It still
uploads the snapshot first if the retry asks for an immediate upload
that the first attempt deferred, and, unless the actor has started
again since, finishes any cleanup the first attempt left undone. If
atelet has already uploaded and detached an async suspend's snapshot,
ateapi records it without node locality.
@msau42

Copy link
Copy Markdown
Collaborator Author

depends on #2890

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants