Enhance TCP timeout configuration for companions

- Added `tcp_timeout` setting to `config.yaml.example` for companion configurations, allowing customization of TCP connection timeouts.
- Updated `RepeaterDaemon` to retrieve and apply the `tcp_timeout` setting, with a default value of 120 seconds.
- Modified `CompanionFrameServer` to accept `client_idle_timeout_sec` parameter, ensuring proper handling of idle timeouts.
- Enhanced API endpoints to include `tcp_timeout` in companion settings, improving configuration visibility and management.
This commit is contained in:
agessaman
2026-03-07 20:39:37 -08:00
parent 1b6f9df489
commit 062dabc46e
4 changed files with 15 additions and 3 deletions

View File

@@ -166,11 +166,13 @@ identities:
# node_name: "RepeaterCompanion"
# tcp_port: 5000
# bind_address: "0.0.0.0"
# tcp_timeout: 120 # seconds; default 120 when omitted; 0 = disable (no timeout)
# - name: "BotCompanion"
# identity_key: "another_companion_identity_key_hex"
# settings:
# node_name: "meshcore-bot"
# tcp_port: 5001
# tcp_timeout: 120 # seconds; default 120 when omitted; 0 = disable (no timeout)
# Radio hardware type
# Supported:

View File

@@ -33,6 +33,7 @@ class CompanionFrameServer(_BaseFrameServer):
companion_hash: str,
port: int = 5000,
bind_address: str = "0.0.0.0",
client_idle_timeout_sec: Optional[int] = 120,
sqlite_handler=None,
local_hash: Optional[int] = None,
stats_getter=None,
@@ -43,6 +44,7 @@ class CompanionFrameServer(_BaseFrameServer):
companion_hash=companion_hash,
port=port,
bind_address=bind_address,
client_idle_timeout_sec=client_idle_timeout_sec,
device_model="pyMC-Repeater-Companion",
device_version=None, # use FIRMWARE_VER_CODE from pyMC_core
build_date="13 Feb 2026",

View File

@@ -432,6 +432,8 @@ class RepeaterDaemon:
node_name = settings.get("node_name", name)
tcp_port = settings.get("tcp_port", 5000)
bind_address = settings.get("bind_address", "0.0.0.0")
tcp_timeout_raw = settings.get("tcp_timeout", 120)
client_idle_timeout_sec = None if tcp_timeout_raw == 0 else int(tcp_timeout_raw)
def _make_sync_node_name_to_config(companion_name: str):
"""Return a callback that syncs node_name to config for this companion (binds name at creation)."""
@@ -525,6 +527,7 @@ class RepeaterDaemon:
companion_hash=companion_hash_str,
port=tcp_port,
bind_address=bind_address,
client_idle_timeout_sec=client_idle_timeout_sec,
sqlite_handler=sqlite_handler,
local_hash=self.local_hash,
stats_getter=self._get_companion_stats,
@@ -544,7 +547,7 @@ class RepeaterDaemon:
logger.info(
f"Loaded companion '{name}': hash=0x{companion_hash:02x}, "
f"port={tcp_port}, bind={bind_address}"
f"port={tcp_port}, bind={bind_address}, client_idle_timeout_sec={client_idle_timeout_sec}"
)
except Exception as e:
@@ -609,6 +612,8 @@ class RepeaterDaemon:
node_name = settings.get("node_name", name)
tcp_port = settings.get("tcp_port", 5000)
bind_address = settings.get("bind_address", "0.0.0.0")
tcp_timeout_raw = settings.get("tcp_timeout", 120)
client_idle_timeout_sec = None if tcp_timeout_raw == 0 else int(tcp_timeout_raw)
bridge = RepeaterCompanionBridge(
identity=identity,
@@ -675,6 +680,7 @@ class RepeaterDaemon:
companion_hash=companion_hash_str,
port=tcp_port,
bind_address=bind_address,
client_idle_timeout_sec=client_idle_timeout_sec,
sqlite_handler=sqlite_handler,
local_hash=self.local_hash,
stats_getter=self._get_companion_stats,
@@ -694,7 +700,7 @@ class RepeaterDaemon:
logger.info(
f"Hot-reload: Loaded companion '{name}': hash=0x{companion_hash:02x}, "
f"port={tcp_port}, bind={bind_address}"
f"port={tcp_port}, bind={bind_address}, client_idle_timeout_sec={client_idle_timeout_sec}"
)
async def _on_raw_rx_for_companions(self, data: bytes, rssi: int, snr: float) -> None:

View File

@@ -2411,6 +2411,8 @@ class APIEndpoints:
"tcp_port": settings.get("tcp_port", 5000),
"bind_address": settings.get("bind_address", "0.0.0.0"),
}
if "tcp_timeout" in settings:
comp_settings["tcp_timeout"] = settings["tcp_timeout"]
new_identity = {
"name": name,
"identity_key": identity_key,
@@ -2609,7 +2611,7 @@ class APIEndpoints:
identity["settings"] = {}
# Only allow companion settings
for k, v in data["settings"].items():
if k in ("node_name", "tcp_port", "bind_address"):
if k in ("node_name", "tcp_port", "bind_address", "tcp_timeout"):
identity["settings"][k] = v
companions[identity_index] = identity