| index 927beaa65..8eaed9b22 100644 |
| --- a/cmd/moveprobe/README.md |
| +++ b/cmd/moveprobe/README.md |
| @@ -65,8 +65,8 @@ curl -H "Authorization: Bearer $MOVEPROBE_SECRET" https://mp1.example.com/report |
| |
| | path | who can call it | what it does | |
| |---|---|---| |
| -| `/` and `/ready` | anyone | 200 when the key file, the platform key, the stored object and the secret all check out. Otherwise 500 with every failed check. A move probes `/`. | |
| -| `GET /report` | `MOVEPROBE_SECRET` | JSON: row counts by kind and region with their lowest and highest sequence numbers, the timer fires by name and due time, both key fingerprints, the stored object, whether the secret is set, the worker's pid, and the region the app saw. | |
| +| `/` and `/ready` | anyone | 200 when the key file, the platform key, the stored object and the secret all check out, and the worker's writes are landing. Otherwise 500 with every failed check. A move probes `/`. | |
| +| `GET /report` | `MOVEPROBE_SECRET` | JSON: row counts by kind and region with their lowest and highest sequence numbers, the timer fires by name and due time, both key fingerprints, the stored object, whether the secret is set, the worker's pid and failed writes, and the region the app saw. Any failed database read makes it a 500, never a partial report. | |
| | `POST /arm-once?in=<seconds>` | `MOVEPROBE_SECRET` | Arms a once-timer named `once-<n>` that calls `/once` after that many seconds. Answers 503 when the instance has no control socket. | |
| | `POST /tick`, `POST /once` | the platform | Timer fires. Each one writes a row with the timer's name and due time. | |
| |
| @@ -108,3 +108,78 @@ the app's output. Stopping the app does not stop the worker. That is the |
| point: it shows whether a move's stop really stops every process the |
| instance started. Once the app has gone, the worker keeps writing for 60 |
| seconds and then exits by itself. |
| + |
| +The worker tells the app whether each write landed. `/report` shows how many |
| +failed, how many of the latest failed in a row, and the last error. After |
| +five failures in a row, `/ready` fails until a write lands again. |
| + |
| +## Strings |
| + |
| +Every body the app can send, and when. Text in angle brackets is filled in |
| +when the app answers. `/ready` joins its failed checks with `; `. |
| + |
| +On `/` and `/ready`: |
| + |
| +- `ready`: every check passed (200). |
| +- `before-write mode: this box writes nothing`: the failure switch names |
| + this region with no suffix. Every path gives this answer (503). |
| +- `after-write mode: not ready here`: the failure switch names this region |
| + with `,after-write` (503). |
| +- `key mismatch: instance.key exists but the database has no key`: the |
| + files directory has a key file, but the database never recorded one |
| + (500). |
| +- `key mismatch: instance.key is missing`: the database has a key, but the |
| + file is gone (500). |
| +- `key mismatch: instance.key differs from the database`: the file and the |
| + database hold different keys (500). |
| +- `key mismatch: instance.key: <error>`: the file is there but cannot be |
| + read (500). |
| +- `CARLOS_INSTANCE_KEY is not set`: the platform key is missing (500). |
| +- `CARLOS_INSTANCE_KEY differs from the one seen at first boot`: the |
| + platform key changed (500). |
| +- `MOVEPROBE_SECRET is not set`: the sealed secret is missing (500). |
| +- `store: <names> not set`: one or more of the store variables is missing |
| + (500). |
| +- `store: put <key>: <error>`: the boot's object could not be written |
| + (500). |
| +- `store: get <key>: <error>`: the boot's object could not be read back |
| + (500). |
| +- `store: <key> reads back different bytes`: the object came back changed |
| + (500). |
| +- `worker: <n> writes failed in a row: <error>`: the worker is alive but |
| + its last five or more writes failed (500). |
| + |
| +On `/report`: |
| + |
| +- The JSON report (200). |
| +- `report: <error>`: a database read failed (500). |
| + |
| +On `/arm-once`: |
| + |
| +- `{"name": "once-<n>", "at": "<time>", "due_at": <unix seconds>}`: the |
| + timer is armed (200). |
| +- `in: want whole seconds, at most 400 days`: `in` is missing or out of |
| + range (400). |
| +- `no control socket: CARLOS_CONTROL_SOCKET is not set`: the instance has |
| + no control socket (503). |
| +- `CARLOS_ADMIN_TOKEN is not set`: the instance has no admin token, so it |
| + cannot arm timers (503). |
| +- `database: <error>`: the timer number could not be taken (500). |
| +- `control socket: <error>`: the request to the control socket could not be |
| + made or sent (500 or 502). |
| +- `control socket: <status> <reply>`: the control socket refused the timer |
| + (502). |
| + |
| +On `/tick` and `/once`: |
| + |
| +- `ok`: the fire is recorded (200). |
| +- `want X-Carlos-Schedule and X-Carlos-Schedule-At`: a fire without the |
| + timer's name or due time (400). |
| +- `database: <error>`: the row could not be written (500). |
| + |
| +On `/report`, `/arm-once`, `/tick` and `/once`: |
| + |
| +- `unauthorized`: the bearer is missing or wrong (401). |
| + |
| +Anywhere else, Go's own answers: `404 page not found` for an unknown path, |
| +and `Method Not Allowed` for a known path with the wrong method (405). |