Skip to content

How it works

The parts of a cf-orbs install and how a job from Amp moves through them.

Updated

A cf-orbs install has three parts, and all three run in your Cloudflare account:

  • The Worker. It starts, pauses and deletes orbs, and keeps track of snapshots. It holds its state in Durable Objects (Cloudflare’s small stateful objects, each with its own storage).
  • The provider container. It runs amp orb provider, which takes jobs from Amp over an outbound connection.
  • The orbs. One Cloudflare Container for each Amp thread.

Terms

  • Control plane. The Worker and its Durable Objects. They start, pause and delete orbs.
  • Dispatch. dispatch.sh, the small shell program that the provider runs once for each job. It passes the job to the control plane.
  • Bootstrap. amp orb bootstrap, the Amp start-up step inside an orb. It connects the orb to Amp.
  • Watchdog. A timer in each orb’s Durable Object. It checks awake orbs and pauses the ones that stay awake too long.
  • Prewarm. Throwaway orb instances that the Worker starts after a deploy. They pull the new image onto hosts and prove that the image starts.
  • tini. A small init program. It runs as process 1 in the orb and reaps stopped processes.

Diagram

Amp ---outbound---> provider container (amp orb provider -> dispatch.sh)
                          |  POST /v1/orbs/<id>/ops   (bearer: control token)
                          v
          Worker "cf-orbs"
            |- OrbSession Durable Object (one per orb) --> orb container
            |- Registry Durable Object (snapshots, awake orbs)
            '- ProviderHost Durable Object --> provider container

The parts

Part Job
Worker Serves the /v1 API. Holds all state in Durable Objects.
OrbSession One for each orb, named orb:<ORB_ID>. Runs spawn, pause and delete. Owns the container, the snapshot and the watchdog alarm.
Registry One for each install. Maps an Amp snapshot id to a Cloudflare snapshot. Lists every snapshot. Counts awake orbs for maxRunning.
ProviderHost Starts the provider container and keeps it running.
Provider container Runs amp orb provider with the Amp provider token. For each job, it runs dispatch.sh.
Orb container The Amp orb image plus tini. One for each thread.

For more on each part, see Provider and dispatch, Orb lifecycle and Orb image.

How a job moves

  1. Amp sends the provider one of three operations: spawn, pause or delete.
  2. dispatch.sh turns the job into one Worker operation: POST /v1/orbs/<id>/ops.
  3. dispatch.sh then long-polls GET /v1/ops/<opId> and prints each progress line. Amp shows the lines in the thread setup log.
  4. The operation ends as succeeded or failed, and dispatch.sh exits 0 or 1.

The same job always returns the same operation, so a retry from Amp attaches to the operation that’s already running.

Spawn order

On spawn, the first match wins:

  1. The orb container is running: reuse it.
  2. The orb has its own snapshot: restore it.
  3. The orb is new, and Amp sent a project snapshot id that maps to a snapshot: restore that, and skip repo setup.
  4. Otherwise, start from the orb image.

After that, amp orb bootstrap starts in its own process group. The spawn succeeds when the bootstrap runs and Amp reports it connected.

Control token and API

The CLI and the provider use the same /v1 API, with the control token as the bearer. The control token is in .cf-orbs/control-token (mode 600) and in the Worker secret CONTROL_TOKEN.

In Cloudflare provider mode, dispatch.sh reaches the API at http://control.internal. The Worker routes that host inside Cloudflare, so the provider sends no bearer. The public API is on as well, and it needs the bearer.

If CONTROL_TOKEN isn’t set on the Worker, every public route returns 404.

Watchdog

A 60 s alarm checks each awake orb. It pauses the orb if it has stayed awake longer than maxAwakeHours, or if its bootstrap died. The alarmSeconds key sets the interval.

Type to search…

↑↓ navigate↵ selectEsc close