🚧 Add broker status page
This commit is contained in:
@@ -61,6 +61,9 @@ class DynsecClient:
|
||||
self._lock = threading.Lock()
|
||||
self._responses: dict[str, queue.Queue[dict[str, Any]]] = {}
|
||||
self._connected = threading.Event()
|
||||
# Optional tap for $SYS telemetry (app.metrics registers itself
|
||||
# at startup). Receives (topic, payload) for every $SYS message.
|
||||
self._event_sink = None
|
||||
|
||||
# -- connection lifecycle ------------------------------------------------
|
||||
def connect(self) -> None:
|
||||
@@ -118,12 +121,25 @@ class DynsecClient:
|
||||
return
|
||||
self._teardown_locked()
|
||||
|
||||
def set_event_sink(self, sink) -> None:
|
||||
"""Register a callable receiving every $SYS message (topic, payload).
|
||||
|
||||
Used by app.metrics for the broker dashboard (spec sections 33,
|
||||
55). The sink must never raise: telemetry must not be able to
|
||||
disturb the management channel.
|
||||
"""
|
||||
self._event_sink = sink
|
||||
|
||||
# -- paho callbacks -------------------------------------------------------
|
||||
def _on_connect(self, client, userdata, flags, reason_code, properties) -> None:
|
||||
if reason_code == 0:
|
||||
# FIXED response topic — all commands reply here; requests are
|
||||
# matched by the correlationData echo inside the payload.
|
||||
client.subscribe(RESPONSE_TOPIC, qos=1)
|
||||
# $SYS telemetry for the dashboard (spec sections 33, 55).
|
||||
# qos 0: telemetry is periodically republished, losing one
|
||||
# is harmless.
|
||||
client.subscribe("$SYS/#", qos=0)
|
||||
self._connected.set()
|
||||
else:
|
||||
logger.error("dynsec client connect failed: %s", reason_code)
|
||||
@@ -149,6 +165,14 @@ class DynsecClient:
|
||||
|
||||
def _on_message(self, client, userdata, msg) -> None:
|
||||
if msg.topic != RESPONSE_TOPIC:
|
||||
# Not a dynsec reply: forward $SYS telemetry to the sink, if
|
||||
# one is registered. Swallow sink errors — telemetry must
|
||||
# never disturb the management channel.
|
||||
if msg.topic.startswith("$SYS/") and self._event_sink is not None:
|
||||
try:
|
||||
self._event_sink(msg.topic, msg.payload)
|
||||
except Exception: # noqa: BLE001
|
||||
logger.warning("$SYS event sink raised; message dropped")
|
||||
return
|
||||
try:
|
||||
payload = json.loads(msg.payload.decode("utf-8"))
|
||||
|
||||
Reference in New Issue
Block a user