Files
crypto_monitor/lib/hub/hub_poll_wait_lib.py

46 lines
1.3 KiB
Python

"""中控后台轮询等待:防止 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