fix(gateway): use os._exit instead of SystemExit for MQTT error handling
SystemExit only stops the paho-mqtt background thread, leaving the main asyncio loop running silently. os._exit kills the entire process so systemd can restart the gateway automatically.
This commit is contained in:
@@ -78,15 +78,17 @@ class Gateway:
|
|||||||
log.info("Successfully connected to MQTT broker")
|
log.info("Successfully connected to MQTT broker")
|
||||||
else:
|
else:
|
||||||
log.error(f"Failed to connect to MQTT broker — reason code: {reason_code}")
|
log.error(f"Failed to connect to MQTT broker — reason code: {reason_code}")
|
||||||
|
os._exit(1)
|
||||||
|
|
||||||
# Callback triggered on disconnection — exit so systemd restarts the gateway.
|
# Callback triggered on disconnection — kill the process so systemd
|
||||||
# This handles cases where the broker becomes unreachable after the initial
|
# restarts the gateway automatically after RestartSec=10 seconds.
|
||||||
# connection (e.g. network instability). Systemd will restart the gateway
|
# os._exit(1) is used instead of SystemExit because on_disconnect runs
|
||||||
# after RestartSec=10 seconds, retrying the connection automatically.
|
# in the paho-mqtt background thread — SystemExit would only stop that
|
||||||
|
# thread, leaving the main asyncio loop running silently.
|
||||||
def on_disconnect(client, userdata, flags, reason_code, properties):
|
def on_disconnect(client, userdata, flags, reason_code, properties):
|
||||||
log.error(f"Disconnected from MQTT broker — reason code: {reason_code}")
|
log.error(f"Disconnected from MQTT broker — reason code: {reason_code}")
|
||||||
log.error("Exiting — systemd will restart the gateway")
|
log.error("Exiting — systemd will restart the gateway")
|
||||||
raise SystemExit(1)
|
os._exit(1)
|
||||||
|
|
||||||
# Callback to confirm message delivery to broker
|
# Callback to confirm message delivery to broker
|
||||||
def on_publish(client, userdata, mid, reason_code, properties):
|
def on_publish(client, userdata, mid, reason_code, properties):
|
||||||
@@ -168,6 +170,9 @@ class Gateway:
|
|||||||
def publish(self, mac: str, data: dict):
|
def publish(self, mac: str, data: dict):
|
||||||
"""Publish decoded sensor data to MQTT broker.
|
"""Publish decoded sensor data to MQTT broker.
|
||||||
Topic: {gateway_id}/{thingy_mac}/update
|
Topic: {gateway_id}/{thingy_mac}/update
|
||||||
|
|
||||||
|
Checks the return code of mqttc.publish() and exits if an error
|
||||||
|
is detected, so systemd can restart the gateway automatically.
|
||||||
"""
|
"""
|
||||||
topic = f"{self.gateway_id}/{mac}/update"
|
topic = f"{self.gateway_id}/{mac}/update"
|
||||||
payload = {
|
payload = {
|
||||||
@@ -184,7 +189,15 @@ class Gateway:
|
|||||||
if "battery" in data:
|
if "battery" in data:
|
||||||
payload["battery"] = data["battery"]
|
payload["battery"] = data["battery"]
|
||||||
|
|
||||||
self.mqttc.publish(topic, json.dumps(payload))
|
result = self.mqttc.publish(topic, json.dumps(payload))
|
||||||
|
|
||||||
|
# Check if publish was successful — rc=0 means success
|
||||||
|
# Any other value indicates an error (e.g. connection lost)
|
||||||
|
if result.rc != mqtt.MQTT_ERR_SUCCESS:
|
||||||
|
log.error(f"Failed to publish to {topic} — rc: {result.rc}")
|
||||||
|
log.error("Exiting — systemd will restart the gateway")
|
||||||
|
os._exit(1)
|
||||||
|
|
||||||
log.info(f"Published to {topic} : {payload}")
|
log.info(f"Published to {topic} : {payload}")
|
||||||
|
|
||||||
def on_device_found(self, device, adv_data):
|
def on_device_found(self, device, adv_data):
|
||||||
|
|||||||
Reference in New Issue
Block a user