mirror of
https://github.com/CyberMind-FR/secubox-deb.git
synced 2026-07-29 09:14:33 +00:00
fix(meshtastic): daemon survives an unreachable MQTT broker at startup (ref #897)
Deploy found a crash-loop: the shipped default config has [shared_grid] set, but the opt-in mosquitto is not running, so Bridge.start()/the paho adapter's synchronous connect() raised ConnectionRefusedError and killed the daemon. Bridge.start() now skips an unreachable broker (log + continue); the paho adapter uses connect_async + loop_start (non-blocking, auto-reconnect). +regression test. Co-Authored-By: Gerald KERMA <devel@cybermind.fr>
This commit is contained in:
parent
4cdae8d1eb
commit
66366537df
|
|
@ -3,11 +3,14 @@
|
|||
"""SecuBox-Deb :: meshtastic — host-side serial↔MQTT bridge (grid-policy driven)."""
|
||||
from __future__ import annotations
|
||||
import json
|
||||
import logging
|
||||
from typing import Callable
|
||||
from .config import Config
|
||||
from .gridpolicy import targets_for
|
||||
from .model import Packet
|
||||
|
||||
_log = logging.getLogger("secubox.meshtastic.bridge")
|
||||
|
||||
|
||||
class Bridge:
|
||||
def __init__(self, cfg: Config, mqtt_factory: Callable[[str], object]) -> None:
|
||||
|
|
@ -25,7 +28,15 @@ class Bridge:
|
|||
except ValueError:
|
||||
port_num = 1883
|
||||
cli = self._factory(tgt)
|
||||
cli.connect(host, port_num)
|
||||
try:
|
||||
cli.connect(host, port_num)
|
||||
except Exception as exc:
|
||||
# A configured broker that is DOWN at startup (e.g. the opt-in
|
||||
# private mosquitto not yet running) must NOT crash the daemon —
|
||||
# skip this target; it can be reconnected when the broker is up.
|
||||
_log.warning("bridge: %s broker %s:%s unreachable at start (%s); skipping",
|
||||
tgt, host, port_num, exc)
|
||||
continue
|
||||
self._clients[tgt] = cli
|
||||
|
||||
def publish(self, channel_name: str, p: Packet) -> None:
|
||||
|
|
|
|||
|
|
@ -70,7 +70,10 @@ class _PahoAdapter:
|
|||
self._client = client
|
||||
|
||||
def connect(self, host: str, port: int) -> None:
|
||||
self._client.connect(host, port)
|
||||
# connect_async (not connect): a broker that is DOWN at startup must not
|
||||
# raise/crash the daemon — loop_start's background thread establishes and
|
||||
# auto-reconnects the connection when the broker becomes reachable.
|
||||
self._client.connect_async(host, port)
|
||||
self._client.loop_start()
|
||||
|
||||
def publish(self, topic: str, payload: str) -> None:
|
||||
|
|
|
|||
|
|
@ -1,3 +1,14 @@
|
|||
secubox-meshtastic (0.1.1-1~bookworm1) bookworm; urgency=medium
|
||||
|
||||
* Fix daemon crash-loop when a configured MQTT broker is down at startup
|
||||
(deploy #897): the opt-in private mosquitto is not running by default, and
|
||||
Bridge.start() / the paho adapter's synchronous connect() raised
|
||||
ConnectionRefusedError → the daemon died. Bridge.start() now skips an
|
||||
unreachable broker (logs + continues), and the paho adapter uses
|
||||
connect_async + loop_start (non-blocking, auto-reconnect).
|
||||
|
||||
-- Gerald KERMA <devel@cybermind.fr> Tue, 22 Jul 2026 12:30:00 +0200
|
||||
|
||||
secubox-meshtastic (0.1.0-1~bookworm1) bookworm; urgency=medium
|
||||
|
||||
* Initial release: multi-grid Meshtastic LoRa node integration (ref #897).
|
||||
|
|
|
|||
|
|
@ -36,3 +36,17 @@ def test_on_channel_publishes_only_when_enabled():
|
|||
made={}
|
||||
b=Bridge(_cfg(["off","on"], on=True), lambda k: made.setdefault(k, FakeMqtt())); b.start(); b.publish("fam", _p())
|
||||
assert "on" in made and made["on"].conn==("mqtt.x.org",8883)
|
||||
|
||||
|
||||
class RefusingMqtt(FakeMqtt):
|
||||
def connect(self, host, port):
|
||||
raise ConnectionRefusedError("broker down")
|
||||
|
||||
|
||||
def test_start_tolerates_unreachable_broker():
|
||||
# A configured broker that is DOWN at startup must not crash Bridge.start()
|
||||
# (the daemon's #897 deploy bug: opt-in mosquitto not running).
|
||||
from api.bridge import Bridge
|
||||
b = Bridge(_cfg(["off", "shared"]), lambda k: RefusingMqtt())
|
||||
b.start() # must not raise
|
||||
b.publish("fam", _p()) # no client registered → no-op, no crash
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user