Skip to content

Start / stop / restart

Bringing a Host up cleanly and down cleanly are not symmetric — start has to spawn NATS first, stop has to wait for NATS to actually exit before returning. This page documents both.

On a .deb-managed Host (systemd)

systemd is the supervisor. Use systemctl directly:

bash
sudo systemctl start hivecast-nats.service hivecast-host.service
sudo systemctl stop hivecast-host.service hivecast-nats.service
sudo systemctl restart hivecast-host.service     # restarts host-service only, NATS stays up
sudo systemctl status hivecast-host.service hivecast-nats.service

The unit file's Requires=hivecast-nats.service enforces the start ordering — systemd refuses to start hivecast-host if NATS isn't up. The reverse (stopping host-service while NATS keeps running) is the whole point of splitting them: short host-service restarts don't blow away the bus.

A full restart of both:

bash
sudo systemctl restart hivecast-nats.service hivecast-host.service

The journald rate-limit (200 msgs / 10s, capped at 2 GB total) is from the postinst — see Service install.

On a source-checkout / npm-style install

Use the wrapper.

Start

bash
hivecast start --home /tmp/matrix-home

What runs (startHostProduct at hivecast.mjs:1464-1509):

  1. Existing-Host short-circuit: if host.status.json shows status: "running" and the recorded pid is alive, the function returns that status and re-runs bootstrapDefaultHostRuntimes (idempotent — already-running runtimes are skipped). It does NOT spawn a new Host.
  2. Start NATS sibling: startNatsSibling (hivecast.mjs:654-685). If the pidfile already shows a live NATS, return as { alreadyRunning: true, pid }. Otherwise spawn nats-server -c <conf> detached + unref + windowsHide, write the pidfile, wait up to 10s for the configured TCP port to accept connections.
  3. Spawn the host-service supervisor: detached, stdio to <MATRIX_HOME>/logs/host.{stdout,stderr}.log. MATRIX_HOST_HOME is set in the child env.
  4. Wait for host.status.json: up to 15s. If the supervisor exits before writing it, throw "Matrix Host Service exited before writing running status".
  5. Wait for the CLI to be ready: probe host-service status until it succeeds, up to 30s.
  6. Bootstrap default runtimes: unless HIVECAST_SKIP_DEFAULT_RUNTIMES=1 or --no-default-runtimes.

Total cold-start budget: up to ~45s in the worst case. Typical is under 5s.

Stop

bash
hivecast stop --home /tmp/matrix-home

What runs (stopHostProduct at hivecast.mjs:1541-1593):

  1. Spawn host-service stop --home <MATRIX_HOME> and wait for it to exit. Capture exit code; do not throw yet on failure.
  2. Always run stopNatsSibling(<MATRIX_HOME>) (hivecast.mjs:687-723) regardless of step 1's outcome.
  3. stopNatsSibling reads the pidfile, sends SIGTERM, waits up to 3s for the process to exit, escalates to SIGKILL if needed, removes the pidfile.
  4. If host-service stop failed but NATS was successfully cleaned up, surface the host failure to stderr with NATS pid info.

The reason NATS is cleaned up unconditionally: even if the Host crashed, NATS is its own process with its own pidfile — it must come down for the next start to bind cleanly.

Source: CLAUDE.md mentions: "After commit 4f733013 (P1.30), stop correctly tears down the NATS sibling — earlier versions leaked it." The await stopNatsSibling is what made stop reliable.

Restart

There is no hivecast restart. Use:

bash
hivecast stop --home /tmp/matrix-home
hivecast start --home /tmp/matrix-home

The hivecast stop waits for NATS to actually exit before returning, so the immediate hivecast start will bind a clean port. Without that wait, you'd race a half-shutdown NATS still binding 4222 — see the comment block at hivecast.mjs:700-708.

If you only need to restart a runtime (not the whole Host), use:

bash
hivecast down <runtime-id> --home /tmp/matrix-home
hivecast up <package> --runtime-id <runtime-id> --startup auto --restart always --home /tmp/matrix-home

…or invoke host.control directly to issue a runtime restart (target state — surfacing this through hivecast CLI is filed under launch readiness).

Behaviour on system reboot

  • .deb install: hivecast-{nats,host}.service are WantedBy=multi-user.target; the postinst systemctl enables them. The Host comes up automatically on reboot. The hivecast-host-service-run shim runs bootstrap-default-runtimes after the supervisor is healthy, bringing all startup: auto runtimes back up.
  • Source-checkout install (no systemd): the Host does NOT auto-start. Run hivecast start --home <MATRIX_HOME> after login. Wire it into your shell's startup if needed.

Behaviour on crash

If the host-service process crashes:

  • .deb install: systemd sees Restart=on-failure and restarts it after 5s (RestartSec=5s). After 5 failures within 60s (StartLimitBurst=5, StartLimitIntervalSec=60), systemd stops trying.
  • Source-checkout install: nothing restarts it. You'll see stale host.status.json and host.pid files. Run hivecast start again — the start path detects the stale pid and proceeds.

If a runtime crashes:

  • restart: always runtimes are auto-restarted by host-control after a brief backoff.
  • restart: on-failure runtimes are restarted only if exit code != 0.
  • restart: never runtimes go to status: failed and stay there.

The runtimeRecordStaleReason function (hivecast.mjs:1200-1230) cross-checks: if a record says running but the pid is dead OR the pid belongs to a different process (different cmdline/cwd), the record is stale and the runtime is treated as failed.

See also

Source: projects/matrix-3/packages/hivecast/bin/hivecast.mjs lines 1464-1509 (startHostProduct), 1541-1593 (stopHostProduct), 654-685 (startNatsSibling), 687-723 (stopNatsSibling), 1200-1230 (runtimeRecordStaleReason).