Skip to content

Pinboard calls each worker at its registered advertiseUrl. pinned (Python and JS) serves all of these; a custom worker must too. Redirects are never followed.

MethodPathWhenAuth sent
GET/_pinned/challenge?challenge=Every register and heartbeatPinboard-Proxy-Secret
GET/_pinned/statsWorker statsPinboard-Attestation
POST/{namespace}/{id}/_wakeDurability sweep, after a placement was lostPinboard-Attestation, Pinboard-Epoch
POST/{namespace}/{id}/_alarmDurability sweep, for a due alarmPinboard-Attestation, Pinboard-Proxy-Secret, Pinboard-Epoch
ANY/{namespace}/{id}{rest}Every proxied requestPinboard-Attestation, Pinboard-Epoch

Workers verify Pinboard-Attestation against their secret, with aud equal to their sessionId; see Authentication.

Challenge

GET {advertiseUrl}/_pinned/challenge?challenge={challenge}
Pinboard-Proxy-Secret: {secret}

Proves the advertise URL reaches the process that holds secret.

Worker answersPinboard treats it as
200 {"value": "{challengeValue}"}Pass
200 with another valueMismatch: register fails, heartbeat voids the registration
Non-2xx, timeout, connection error, body not receivedRegister fails; heartbeat marks the worker degraded

Timeout: PINBOARD_VERIFY_TIMEOUT_MS, default 2500 ms. Body cap 1 MiB.

pinned answers 404 {"detail":"unknown challenge"} for a challenge other than its current one and 403 {"detail":"invalid proxy secret"} without the secret or a valid attestation.

Stats

GET {advertiseUrl}/_pinned/stats
Pinboard-Attestation: {jws}

Any JSON object. Pinboard relays it as stats and filters two fields to the worker's namespaces visible to the calling operator:

FieldTypeFilter
namespacesobjectOther keys dropped
instancesobject[]Items with another namespace dropped

pinned also sends draining, leaseFlaps, reregistrations and process (uptimeMs, rssBytes; Python adds cpuPercent when psutil is installed).

Timeout 3 s. A non-2xx, timeout or non-object reports the worker as {"error":"unreachable"}.

Wake

POST {advertiseUrl}/{namespace}/{id}/_wake
Pinboard-Attestation: {jws}
Pinboard-Epoch: {epoch}

Sent by the durability sweep to bring back an instance whose placement was overwritten (its owner died or Redis lost it). The worker loads the instance at that epoch.

Worker answersPinboard does
200Done; the marker is cleared
202Still activating; checks again after the wake timeout
OtherBacks off and retries; parks the entry after repeated failures

Mounted only on workers with a durability store. pinned answers 200 {"ok":true}.

Timeout: the sweep's wakeTimeoutMs, default 15000 ms.

Alarm

POST {advertiseUrl}/{namespace}/{id}/_alarm
Pinboard-Attestation: {jws}
Pinboard-Proxy-Secret: {secret}
Pinboard-Epoch: {epoch}

Fires an instance's stored alarm when it is due and no worker is running it, placing the instance if needed.

Worker answers (pinned-js)Meaning
200 {"fired": boolean}Alarm ran, or nothing was due
202 {"fired": false, "running": true}The owner's own timer is running it
409 {"detail": "…"}The epoch lost its fence
403 {"detail":"invalid proxy secret"}Secret missing

The secret is required because proxied client requests carry a valid attestation but never the secret; a client cannot fire an alarm through the proxy. _wake has no such guard.

Only pinned-js mounts _alarm. The Python worker has no _alarm route. TODO(verify): what a Python worker answers when the sweep fires an alarm at it.

Pinboard logs a non-2xx and retries on a later sweep pass.

Data-plane forwards

Every proxied request arrives at {advertiseUrl}/{namespace}/{id}{rest}{query} with the client's method, headers (filtered), and body. See Proxy a request.

Worker answersPinboard does
Any statusRelays it
503 + Pinned-Refusal: lease-unhealthyTreats it as a refused activation: releases, may re-place once, strips the header
502, 503, 504Relays it and counts a failure toward outlier ejection

Five consecutive failures eject a worker from new placements for 30 s, doubling per ejection; at most half the workers are ejected at once.

A non-digit Pinboard-Epoch is answered 400 malformed placement epoch by pinned.