Skip to content

feat(ateapi): record last_resume_time on actors - #950

Open
NekoPunch (orangeCatDeveloper) wants to merge 1 commit into
agent-substrate:mainfrom
orangeCatDeveloper:issue-277-last-resume-time
Open

feat(ateapi): record last_resume_time on actors#950
NekoPunch (orangeCatDeveloper) wants to merge 1 commit into
agent-substrate:mainfrom
orangeCatDeveloper:issue-277-last-resume-time

Conversation

@orangeCatDeveloper

@orangeCatDeveloper NekoPunch (orangeCatDeveloper) commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Part of #277

Actors carry no record of when they last started running, so there is no way to
answer "how long has this actor been up" from the API.

What this adds

A last_resume_time timestamp on Actor, stamped at the single place an actor
transitions into RUNNING:

// workflow_resume.go, finalizeRunning
toUpdate.Status = ateapipb.Actor_STATUS_RUNNING
toUpdate.LastResumeTime = timestamppb.Now()

It is not cleared on suspend or pause — the field answers "when did it last come
up", and stays queryable while the actor is down.

Scope

#277 lists four fields. create_time and update_time already exist on
ResourceMetadata, leaving two; this covers last_resume_time.

total_running_duration is deliberately left out. Unlike an absolute timestamp
written by one replica, a cumulative duration is a subtraction across replicas —
resume stamps on replica A, suspend computes now(B) - last_resume_time(A)
so clock skew can produce a negative delta that accumulates permanently into a
field documented as never resetting. It also needs accounting at all six exits
from RUNNING (crash, syncer crash, suspending, pausing, pause-failure crash,
deleting), and the cut-off for an actor killed without a clean transition is
undefined. Those are design questions, not implementation detail.

Rollout: ateredis unmarshals with strict protojson, so roll all ateapi replicas
forward together, and clear lastResumeTime from stored actors before any
rollback.

Tests

TestFinalizeRunning_SetsLastResumeTime covers the stamp.
TestEnsureSuspendedFinalized_KeepsLastResumeTime pins the preservation
behaviour — it fails with LastResumeTime = 1970-01-01 ..., want 2026-01-01 ...
if the suspend path drops the field.

Timestamps the RUNNING transition, one of agent-substrate#277's two remaining fields
(create_time and update_time already live on ResourceMetadata).
total_running_duration stays out: it is a cross-replica subtraction that
clock skew can drive negative into a monotonic counter, and the crash
cut-off semantics are undefined.

Rollout: ateredis unmarshals with strict protojson, so roll all ateapi
replicas forward together and clear lastResumeTime from stored actors
before any rollback.

Claude-Session: https://claude.ai/code/session_01XuQqkwLf5Zx6CSZFHSC6hb
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.

1 participant