Skip to content

feat: Emulate single-tenant Actor Standby - #76

Merged
Pijukatel merged 6 commits into
masterfrom
claude/ecstatic-cannon-ojf5fm
Sep 24, 2026
Merged

Pijukatel merged 6 commits into
masterfrom
claude/ecstatic-cannon-ojf5fm

Conversation

@Pijukatel

Copy link
Copy Markdown
Collaborator

Standby-enabled Actors (usesStandbyMode or actorStandby) are served over HTTP at their standbyUrl on the API port, including SSE and websockets.
Requests go to STANDBY runs the runtime starts, scales by desired/max requests per run, and winds down gracefully after idleTimeoutSecs, as on the platform.
Actors accept and return the platform's actorStandby settings; the console shows them with a ready-to-open standby link.
Adds TypeScript, Python and web-page standby sample Actors. Multi-tenant Standby stays unsupported.

Closes #60


Generated by Claude Code

claude and others added 6 commits September 23, 2026 13:22
Serve Standby-enabled Actors over HTTP on the API port, at their standbyUrl
(/actor-runtime/standby/<username>--<actor-name>, or <label>.localhost).
Requests are proxied to STANDBY-origin runs that the runtime starts, scales by
desired/max requests per run, and winds down gracefully (SUCCEEDED) after
idleTimeoutSecs, as on the platform. Actors accept and return the actorStandby
settings, and `usesStandbyMode` in .actor/actor.json enables Standby on push.
Adds sample_actor_standby, integration, unit and e2e tests, and updates the
requirements, README and Agent Skill. Multi-tenant Standby stays unsupported.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W6t3FkairFVeCRTVXrJfTw
Replace the minimal sample_actor_standby with sample_actor_standby_ts and
sample_actor_standby_py: the same Actor server in both languages, with JSON
endpoints, a request body echo, a Server-Sent Events stream, a websocket,
request stats kept across runs in a named key-value store, and graceful
shutdown on the idle `aborting` event. The standby e2e test now drives both.

Standby runs also get ACTOR_WEB_SERVER_PORT, as on the platform: the Python
SDK reads the server port from it rather than ACTOR_STANDBY_PORT.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W6t3FkairFVeCRTVXrJfTw
The Actor Standby section now links to the standby URL with the owner's token
already in it, masked in the text shown, plus a button that copies the full
link - so a standby Actor can be tried in a browser with one click.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W6t3FkairFVeCRTVXrJfTw
- `standbyUrl` is now `http://<username>--<actor-name>.localhost:3333`,
the local counterpart of `https://<username>--<actor-name>.apify.actor`:
the Actor owns `/` of its own origin, one hostname per Actor.
- Fixes Actor web UIs with root-relative links (e.g.
`fetch('/api/...')`), which under `/actor-runtime/standby/<label>/`
escaped to the runtime's own API and broke Actors that work on the
platform.
- `/actor-runtime/standby/<label>/...` stays for clients that do not
resolve `*.localhost`; the Actor object read from an Actor container
carries `http://apify-api:3333/actor-runtime/standby/<label>`, which
other Actors can reach.
- Standby Actors now also work under rootless Podman 3.x, where the
runtime could not reach a standby run's server.
- Storage lists (`GET /v2/datasets`, `/v2/key-value-stores`,
`/v2/request-queues`) return only named storages unless `?unnamed=true`,
as on the platform.
- Adds `sample_actor_standby_web` and e2e tests for an external client
calling its standby endpoint, and another Actor's run calling it from
its container.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_013KAxkpoSLVQvpEJUANjWdp

---------

Co-authored-by: Claude <noreply@anthropic.com>
@Pijukatel
Pijukatel marked this pull request as ready for review September 24, 2026 11:04
@Pijukatel
Pijukatel merged commit 206fed1 into master Sep 24, 2026
29 checks passed
@Pijukatel
Pijukatel deleted the claude/ecstatic-cannon-ojf5fm branch September 24, 2026 11:11
Pijukatel pushed a commit that referenced this pull request Sep 24, 2026
#76 adds Actor Standby, and with it a new path inside this namespace:
/actor-runtime/standby/<label>, the addressing for clients that cannot
resolve *.localhost. Git merged it without a conflict, but the document
is normative for the namespace and said nothing about it, so:

- `proxyStandbyRequest` is now in the document, with the standbyLabel
  parameter, the two addressings, the fact that every method, sub-path
  and websocket upgrade reaches the Actor (the single GET entry is the
  forwarding operation, not a shape this API defines), the token
  sources and the errors this router produces before the Actor is
  reached.
- `setApiFallbackState`'s exhaustive never-relayed list now says the
  standby addresses are answered by a router ahead of the fallback, so
  no standby-* error can reach it - matching api.md's new "Actor
  Standby" section.
- A fourth x-actor-runtime-platform-notes entry, for GET
  /v2/actors/{actorId}: an Actor's standbyUrl is a local address, and
  is picked from the request's own Host, which the platform's value
  never is. Standby itself is faithful, so nothing else is noted.
- api.md's Actor-runtime section names both in its two pointer bullets;
  the unit test's endpoint and platform-note lists name them too.

Verified: build, lint, format:check, and 1022 tests across 73 files.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016VvUV6661cyYbxoHZv2Pby
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.

Actor Server emulation (formerly standby)

3 participants