Zaroz
Units API guide

Create by key, start, stop and destroy

A unit made by your code has a key: its name, chosen by you, that never changes. A hub that opens a private world per player uses plot-<player>. A job runner uses job-<id>. The key is also the unit's private network name: <key>.<workload-slug>.

These routes need the policy in code mode.

Create a unit by key

POST .../units is idempotent on the key, which makes it safe to call on every "player opens a plot".

curl

TerminalCode
curl -sS -X POST "$UNITS" -H "$AUTH" -H "Content-Type: application/json" -d '{ "key": "plot-ana", "labels": {"kind": "plot", "owner": "ana"}, "user_data": {"world": "s3://my-bucket/plots/ana"}, "start": true, "on_exit": "stop" }' # 201 {"created": true, "unit": {...}} a new unit # 200 {"created": false, "unit": {...}} the live unit with that key already existed

TypeScript

TypeScriptCode
import { call, UNITS } from "./zaroz"; const { status, body } = await call("POST", UNITS, { key: "plot-ana", labels: { kind: "plot", owner: "ana" }, user_data: { world: "s3://my-bucket/plots/ana" }, start: true, on_exit: "stop", }); console.log(status, body.created, body.unit.key, body.unit.state);

Python

Code
from zaroz import call, UNITS status, body = call("POST", UNITS, { "key": "plot-ana", "labels": {"kind": "plot", "owner": "ana"}, "user_data": {"world": "s3://my-bucket/plots/ana"}, "start": True, "on_exit": "stop", }) print(status, body["created"], body["unit"]["key"], body["unit"]["state"])
SituationAnswer
No live unit has this key201 {created: true} and the unit starts (unless "start": false)
A live unit has this key and is running, input equal or omitted200 {created: false} with the current unit
It is stopped and start is trueIt starts. labels and user_data, when you send them, replace the stored ones. 200 {created: false}
It is running and you send different labels or user_data409 unit-input-differs. A running unit's input changes only by allocate or PATCH labels

Fields: key (required), labels, user_data, start (default true), on_exit (restart, stop or destroy; default the policy's default_on_exit).

"start": false creates the unit stopped: it holds no slot and costs nothing until you start it.

on_exit is what happens when the unit's process exits: restart keeps the pod and restarts the process in place, stop and destroy end the unit (and release the slot). Use destroy for a match or a job, stop for a plot you will come back to.

Read a unit

curl

TerminalCode
curl -sS "$UNITS/plot-ana" -H "$AUTH"

TypeScript

TypeScriptCode
const { body: unit } = await call("GET", `${UNITS}/plot-ana`); console.log(unit.state, unit.labels, unit.user_data, unit.allocation);

Python

Code
_, unit = call("GET", f"{UNITS}/plot-ana") print(unit["state"], unit["labels"], unit["user_data"], unit["allocation"])

The response carries state, desired_state, labels, user_data, origin (policy, code or warm), allocation (null until allocated), private_name, public_endpoints, billing_class (included or extra), the current pod and the restart count.

Stop, start and destroy

curl

TerminalCode
curl -sS -X POST "$UNITS/plot-ana/stop" -H "$AUTH" # drain, then stop: costs nothing while stopped curl -sS -X POST "$UNITS/plot-ana/start" -H "$AUTH" -H "Content-Type: application/json" -d '{}' curl -sS -X DELETE "$UNITS/plot-ana" -H "$AUTH" # drain, then destroy: final

TypeScript

TypeScriptCode
await call("POST", `${UNITS}/plot-ana/stop`); await call("POST", `${UNITS}/plot-ana/start`, {}); // {} starts it as it is await call("DELETE", `${UNITS}/plot-ana`); // final; the key may be reused afterwards

Python

Code
call("POST", f"{UNITS}/plot-ana/stop") call("POST", f"{UNITS}/plot-ana/start", {}) # {} starts it as it is call("DELETE", f"{UNITS}/plot-ana") # final; the key may be reused afterwards
  • stop drains the unit (it receives a draining notice and stops accepting new work), then stops it. Key, labels and user_data are kept, the slot is released and nothing is billed while it is stopped. Stopping a stopped unit is a no-op 200.
  • start wakes a stopped unit. Starting a running unit is a no-op 200. The body may carry labels and user_data, each replacing the stored value whole. Send {} to start it as it is.
  • destroy drains and then removes the unit. It is final: afterwards the key answers 404 and may be reused. Success is 204.

curl

TerminalCode
curl -sS -X POST "$UNITS/plot-ana/start" -H "$AUTH" -H "Content-Type: application/json" \ -d '{"labels": {"kind": "plot", "owner": "ana", "tier": "vip"}, "user_data": {"world": "s3://my-bucket/plots/ana-v2"}}'

TypeScript

TypeScriptCode
await call("POST", `${UNITS}/plot-ana/start`, { labels: { kind: "plot", owner: "ana", tier: "vip" }, user_data: { world: "s3://my-bucket/plots/ana-v2" }, // replaces the stored value whole });

Python

Code
call("POST", f"{UNITS}/plot-ana/start", { "labels": {"kind": "plot", "owner": "ana", "tier": "vip"}, "user_data": {"world": "s3://my-bucket/plots/ana-v2"}, # replaces the stored value whole })

Every call that starts a pod (create with start, start, a refill, allocate with if_none: create) is checked against your limits and spend cap: see Errors for container-unit-limit, org-unit-limit, start-rate and spend-cap. A refusal is never a partial success, and running units are never touched by a limit.

Stopped units pile up

A Workload may hold 1,000 stopped units (stopped-unit-limit). Stopped units that stay stopped for longer than the policy's destroy_stopped_after_days (default 90) are destroyed, and a unit.destroyed event with reason expired tells you.

Last modified on