"""中控后台轮询等待:防止 request_refresh 连锁打满 CPU.""" from __future__ import annotations import asyncio import time async def wait_poll_interval( *, refresh: asyncio.Event, stop: asyncio.Event, interval_sec: float, started_at: float, min_early_wake_sec: float | None = None, ) -> None: """距 started_at 至少间隔 interval_sec 再进入下一轮. 期间若收到 refresh:仅当已过 min_early_wake_sec 才提前结束(兼顾手动刷新与防抖). """ interval = max(0.05, float(interval_sec)) min_early = ( float(min_early_wake_sec) if min_early_wake_sec is not None else min(2.0, interval * 0.4) ) while not stop.is_set(): left = interval - (time.monotonic() - started_at) if left <= 0: return refresh.clear() stop_task = asyncio.create_task(stop.wait()) refresh_task = asyncio.create_task(refresh.wait()) done, pending = await asyncio.wait( {stop_task, refresh_task}, timeout=left, return_when=asyncio.FIRST_COMPLETED, ) for t in pending: t.cancel() if stop.is_set(): return if not done: return if refresh_task in done and (time.monotonic() - started_at) >= min_early: return