hbc/server: request InfoPlugin refresh when host has no plugin data; update docs
- Server sets request_update=1 in ACK when host.plugin_data is empty - hbc: AsyncConnection.request_info_event; handle_ack sets it on request_update - hbc: _info_plugin_refresh_loop clears InfoPlugin caches and resends on demand - hbc_mini: same via _request_info event and _info_refresh_loop - docs/USERS.md: document client-declared owner config key - docs/PLUGIN_DEVELOPMENT.md: document server-initiated InfoPlugin refresh Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+22
-8
@@ -791,7 +791,7 @@ class _HeartbeatProtocol(asyncio.DatagramProtocol):
|
||||
msg_id = msg.get("ID")
|
||||
now = time.time()
|
||||
if msg_id == "ACK":
|
||||
self._conn._handle_ack(now)
|
||||
self._conn._handle_ack(msg, now)
|
||||
elif msg_id == "CMD":
|
||||
asyncio.create_task(_handle_command(self._conn, msg))
|
||||
elif msg_id == "UPD":
|
||||
@@ -818,6 +818,7 @@ class AsyncConnection:
|
||||
self.rtts: List[float] = [0.0]
|
||||
self._transport: Optional[asyncio.DatagramTransport] = None
|
||||
self._dead = False
|
||||
self._request_info: asyncio.Event = asyncio.Event()
|
||||
self._log = logging.getLogger(f"hbc.conn.{addr}")
|
||||
|
||||
async def open(self) -> bool:
|
||||
@@ -836,12 +837,14 @@ class AsyncConnection:
|
||||
self._transport.close()
|
||||
self._transport = None
|
||||
|
||||
def _handle_ack(self, now: float):
|
||||
def _handle_ack(self, msg: Dict[str, Any], now: float):
|
||||
rtt = (now - self.lastsend) * 1000.0
|
||||
self.rtts.append(rtt)
|
||||
if len(self.rtts) > 10:
|
||||
self.rtts.pop(0)
|
||||
self.ackcount += 1
|
||||
if msg.get("request_update"):
|
||||
self._request_info.set()
|
||||
|
||||
async def sendto(self, msg: Dict[str, Any], msg_id: str = "HTB"):
|
||||
if self._dead:
|
||||
@@ -974,6 +977,19 @@ async def _run_monitor_group(conn: AsyncConnection, plugins: List[Plugin], inter
|
||||
await _sleep(interval)
|
||||
|
||||
|
||||
async def _info_refresh_loop(conn: AsyncConnection, info: List[Plugin]):
|
||||
log = logging.getLogger("hbc.plugins")
|
||||
while _running:
|
||||
await conn._request_info.wait()
|
||||
if not _running:
|
||||
break
|
||||
conn._request_info.clear()
|
||||
log.info("refreshing InfoPlugins on server request")
|
||||
for plugin in info:
|
||||
plugin._cache = None
|
||||
await _run_info_plugins(conn, info)
|
||||
|
||||
|
||||
async def _plugin_collector(conn: AsyncConnection, plugins: List[Plugin]):
|
||||
info = [p for p in plugins if isinstance(p, InfoPlugin)]
|
||||
monitor = [p for p in plugins if isinstance(p, MonitorPlugin)]
|
||||
@@ -984,12 +1000,10 @@ async def _plugin_collector(conn: AsyncConnection, plugins: List[Plugin]):
|
||||
for p in monitor:
|
||||
by_interval[p.interval].append(p)
|
||||
|
||||
if by_interval:
|
||||
await asyncio.gather(
|
||||
*[asyncio.create_task(_run_monitor_group(conn, grp, iv))
|
||||
for iv, grp in by_interval.items()],
|
||||
return_exceptions=True,
|
||||
)
|
||||
tasks = [asyncio.create_task(_info_refresh_loop(conn, info))]
|
||||
tasks += [asyncio.create_task(_run_monitor_group(conn, grp, iv))
|
||||
for iv, grp in by_interval.items()]
|
||||
await asyncio.gather(*tasks, return_exceptions=True)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user