From 475319e24862ca9786b61068d394b83dbe4432db Mon Sep 17 00:00:00 2001 From: Andreas Wrede Date: Mon, 4 May 2026 09:59:30 -0400 Subject: [PATCH] fix: send boot/shutdown on first open connection, not blindly first in list Replace break-after-first-iteration with next(c for c in connections if c.transport) so the message goes to the first connection that actually has an open transport. Falls back to connections[0] if none are open yet (sendto will attempt reopen), avoiding silent message loss when the leading connection is still connecting. Co-Authored-By: Claude Sonnet 4.6 --- hbd/client/main.py | 17 ++++++----------- scripts/hbc_mini.py | 11 +++++------ 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/hbd/client/main.py b/hbd/client/main.py index 9587385..cfce61f 100644 --- a/hbd/client/main.py +++ b/hbd/client/main.py @@ -463,18 +463,14 @@ async def cleanup(connections: List[AsyncConnection]): logger = logging.getLogger("hbc.cleanup") logger.info("Cleaning up connections") - for conn in connections: + target = next((c for c in connections if c.transport), connections[0] if connections else None) + if target: try: - msg = { - "shutdown": 1, - "acks": conn.ackcount - } - await conn.sendto(msg) + await target.sendto({"shutdown": 1, "acks": target.ackcount}) except Exception as e: logger.error(f"Error sending shutdown: {e}") - + for conn in connections: conn.close() - break # Only send shutdown on first connection to avoid duplicates # Give messages time to send await asyncio.sleep(0.5) @@ -539,9 +535,8 @@ async def async_main(args, config): boot_msg["msg"] = args.message boot_msg["acks"] = 0 - for conn in connections: - await conn.sendto(boot_msg) - break # Only send message on first connection to avoid duplicates + target = next((c for c in connections if c.transport), connections[0]) + await target.sendto(boot_msg) if args.message and not args.daemon: # Message-only mode diff --git a/scripts/hbc_mini.py b/scripts/hbc_mini.py index b056707..a21de83 100755 --- a/scripts/hbc_mini.py +++ b/scripts/hbc_mini.py @@ -1052,9 +1052,8 @@ async def _async_main(args, cfg: Dict[str, Any]) -> int: if args.message: bmsg["service"] = "service" bmsg["msg"] = args.message - for c in connections: - await c.sendto(bmsg) - break + target = next((c for c in connections if c._transport), connections[0]) + await target.sendto(bmsg) if args.message and not args.daemon: await asyncio.sleep(0.3) for c in connections: @@ -1086,12 +1085,12 @@ async def _async_main(args, cfg: Dict[str, Any]) -> int: pass log.info("shutting down") - for conn in connections: + target = next((c for c in connections if c._transport), connections[0] if connections else None) + if target: try: - await conn.sendto({"shutdown": 1, "acks": conn.ackcount}) + await target.sendto({"shutdown": 1, "acks": target.ackcount}) except Exception: pass - break for conn in connections: conn.close() await asyncio.sleep(0.3)