Skip to content

feat(management): relay control channel, relay aggregation and SSE events - #59

Open
hashbk wants to merge 3 commits into
feat/management-api-v2-dynamic-configfrom
feat/management-api-v2-relay-control
Open

hashbk wants to merge 3 commits into
feat/management-api-v2-dynamic-configfrom
feat/management-api-v2-relay-control

Conversation

@hashbk

@hashbk hashbk commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Second step of the management API v2 rework: a single hbbs management endpoint can now aggregate and control any number of hbbr instances, so the console only ever needs one upstream and one credential. Complements #58 (dynamic config) and is independently mergeable.

  • GET /v1/control (WebSocket, hbbs only) — when RD_HBBS_API_URL is set, hbbr opens an outbound WebSocket to hbbs, registers its relay identity (RD_RELAY_ID/HOSTNAME, RD_RELAY_ADDRESS), reports heartbeats (10s), session lifecycle events and session snapshots, and receives policy commands. hbbr never exposes a management listener for aggregation; re-registration replaces the previous connection (generation guard prevents stale sockets from corrupting state), and connections silent for 45s are dropped.
  • Ban policy fan-out — PUT /v1/bans on hbbs pushes the active policy to every registered relay immediately (and on registration). Relays persist the forwarded policy locally, so it stays active across restarts even when hbbs is unreachable. The 10-second polling reconciliation in the console agent becomes unnecessary.
  • Relay discovery — addresses reported at registration are folded into the live relay server list (static relay-servers plus registered relays) through a RelaySync callback, reusing the existing Data::RelayServers0 hot-update channel and the built-in relay health checks.
  • Relay-scoped proxies — GET/PUT /v1/relays/:id/config, GET /v1/relays/:id/logs forward relay configuration and log reads/writes over the control channel using request ids and HTTP-equivalent responses (status + body are forwarded verbatim, so proxied endpoints keep the semantics of the direct ones; a relay that stays silent fails the request after 10 seconds, and pending requests fail fast when the relay disconnects). The relay control client validates, persists and activates forwarded config updates through the same shared core as its own HTTP handler.
  • Restart — POST /v1/restart on both services and POST /v1/relays/:id/restart on hbbs: the process exits shortly after the response is flushed (202, state: restarting), relying on the supervisor (container restart policy or systemd) to bring it back with persisted configuration applied. Relay restarts are fire-and-forget; the relay re-registers when it comes back.
  • New hbbs endpoints — GET /v1/relays (health + aggregation metadata), GET /v1/relays/:id/sessions (aggregated relay sessions), DELETE /v1/relays/:id/sessions/:uuid (proxied disconnect, same 202 closing semantics).
  • GET /v1/events (SSE) — aggregated event stream: peer_online/peer_offline (from snapshot diffing, so short-lived activity is never lost to polling gaps), session_opened/session_closed (with relay_id), relay_registered/relay_disconnected, bans_replaced; 15s keep-alive.
  • Shared core — validate_update, apply_config_update, config_view and logs_view extracted for reuse by both the HTTP handlers and the relay control channel; apply_bans_update likewise; sessions_snapshot/disconnect_session shared by local endpoints and the control client.

Test plan

  • cargo test --lib — 24 passed (new: relay proxy requests incl. status forwarding and fire-and-forget restart, cancellation of pending relay requests)
  • cargo check --locked --all-features --all-targets (CI parity)
  • cargo build --bin hbbs --bin hbbr with no new warnings
  • CI managed-image build

…E events

Let a single hbbs management endpoint aggregate and control any number of
hbbr instances so the console only ever needs one upstream.

- /v1/control (WebSocket, hbbs only): hbbr connects outbound with
  RD_HBBS_API_URL, registers its relay identity, reports heartbeats,
  session lifecycle events and session snapshots, and receives policy
  commands; re-registration replaces the previous connection and stale
  generations are ignored
- ban policies now fan out from hbbs to every registered relay on update
  and on registration; relays persist the forwarded policy locally so it
  stays active across restarts even when hbbs is unreachable
- relay discovery: addresses reported at registration are folded into the
  live relay server list (static relay-servers plus registered relays)
  through a service-registered RelaySync callback
- new hbbs endpoints: GET /v1/relays (health and aggregation metadata),
  GET /v1/relays/:id/sessions (aggregated relay sessions) and
  DELETE /v1/relays/:id/sessions/:uuid (proxied disconnect)
- GET /v1/events (SSE): aggregated event stream with peer online/offline,
  relay session lifecycle, relay registration and policy changes; peer
  events come from snapshot diffing, so nothing is lost to polling gaps
- shared apply_bans_update extracted for the HTTP handler and the relay
  control channel; sessions_snapshot and disconnect_session reused by
  both the local endpoints and the control client
@coderabbitai

coderabbitai Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 866e4151-569c-4c76-b5bc-71e69bb51675

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@hashbk
hashbk changed the base branch from master to feat/management-api-v2-dynamic-config October 16, 2026 16:22
…dpoints

Management clients talk to hbbs only, so relay-scoped configuration reads
and writes, log reads and restarts are proxied over the control channel
using request ids and HTTP-equivalent responses. Extract validate_update,
apply_config_update and logs_view for reuse by the relay control client,
add POST /v1/restart to both services, and cancel pending relay requests
when a relay disconnects.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant