Skip to content

Drills

Rehearse a failure before you rely on the system. The gateway-down drill is the one that matters most.

Gateway-down drill

Run it after the install step of Running, and again before you rely on it. It proves the three claims that matter: the intake keeps answering while the destination is down, nothing grows without bound, and everything is delivered, in order, after. It does not restart or stop the gateway: the destination is made unreachable from hookspool's side, which the dispatcher cannot tell from a real outage.

export HOOKSPOOL_HOME=/var/lib/hookspool
# (set `dry = true` under [alerts] first if you do not want the chat woken; the alert is then only recorded)

# 1. baseline
hookspool status                                   # breaker closed for hermes:*, nothing pending

# 2. take the destination away: point hermes.base_url at a closed port, then reload
sed -i 's#^base_url = .*#base_url = "http://127.0.0.1:9"#' $HOOKSPOOL_HOME/config.toml
hookspool reload

# 3. feed it. Use real traffic, or inject into the dedicated drill route (same validation as the intake; one
#    batch per key, so several keys). hermes:drill needs a Hermes subscription named "drill" that does nothing
#    visible (see below); never inject drill payloads into a real route.
for i in 1 2 3 4 5 6; do
  echo "{\"drill\": $i}" | hookspool enqueue --source drill --key drill-$i --destination hermes:drill --dedup-id drill-$i
done

# 4. watch (give it two minutes: the breaker trips on the third consecutive transport failure)
hookspool status       # hermes:drill breaker: open after 3 transport failures; oldest_pending_age_s grows
hookspool list         # batches sealed or in retry, none dead; no batch exceeds [coalesce] max_events / max_bytes
hookspool issues       # exactly one delivery issue for hermes:drill, one alert (dry: recorded, not sent)
curl -s http://127.0.0.1:8650/healthz   # 200, degraded lists the open breaker. The intake is still taking events.

# 5. restore
sed -i 's#^base_url = .*#base_url = "http://127.0.0.1:8644"#' $HOOKSPOOL_HOME/config.toml
hookspool reload

# 6. confirm recovery (the next probe is within the breaker cooldown, at most 10 minutes)
hookspool status       # breaker closed; the backlog drains FIFO per key
hookspool list --state delivered
hookspool issues       # the issue auto-resolved

Pass criteria: nothing dead; every injected event appears in a delivered batch; the issue opened once and resolved itself; no batch grew past its bounds while the breaker was open. To drill with the real gateway, stop it for a few minutes instead of step 2; that is the same test with the real thing, and the one to run before trusting an upgrade window.

The drill route. Add a drill entry to the Hermes subscriptions file (the one hermes.subscriptions_path names) with a prompt that does nothing visible and deliver set to log (so no chat is messaged), a secret of its own, and no events filter. The restore step delivers the six {"drill": n} payloads to it, and only to it: no real agent is woken with drill data. Real traffic that arrives while the destination is away is held the same way and is delivered after step 5, in order; that is the point of the drill, not a loss. If the drill leaves rows behind, they are test rows: hookspool drop <batch>… --yes for any still pending.