feat(webhook): worker + CLI + systemd unit

Introduces the `decnet webhook` long-running worker that consumes the
internal bus and POSTs matching events to configured subscriptions.

Design: one task per (subscription, pattern) pair. Each task opens
its own bus subscription, iterates events, and dispatches via the
shared deliver() client. No intermediate queue, no in-memory filter
matching — the bus's own pattern matcher is the filter. Reloads on
`system.webhook.subscriptions_changed` signals from the CRUD router,
with a 60s fallback timer in case a signal is lost.

Shutdown propagates via CancelledError on the outer task; all inner
subscription tasks are cancelled and awaited in a finally block.
Bus unavailable → worker stays up in idle mode per the DEBT-031
pattern, logging one warning.

Registered as a master-only CLI command (agents don't configure
webhooks — the subscription store lives on master). systemd unit
mirrors the profiler template; added to decnet.target Wants= list so
`systemctl start decnet.target` brings it up alongside everything
else. `decnet init` auto-picks up the new .service.j2 via its
existing `glob("decnet-*.service.j2")` sweep.
This commit is contained in:
2026-04-24 15:46:11 -04:00
parent b70845a85d
commit e6127a81a1
9 changed files with 583 additions and 3 deletions

View File

@@ -37,6 +37,7 @@ from . import (
topology,
updater,
web,
webhook,
workers,
)
from .gating import _gate_commands_by_mode
@@ -54,7 +55,7 @@ for _mod in (
swarm,
deploy, lifecycle, workers, inventory,
web, profiler, sniffer, db,
topology, bus, geoip, init,
topology, bus, geoip, init, webhook,
):
_mod.register(app)