rate_limit.py 947 B

123456789101112131415161718192021222324252627282930
  1. """跨线程安全的异步请求间隔限速。
  2. find_agent 以多线程跑时,每个 worker 自建事件循环;不能用 asyncio.Lock 做进程级限速。
  3. """
  4. from __future__ import annotations
  5. import asyncio
  6. import threading
  7. import time
  8. from collections.abc import Awaitable, Callable
  9. def make_async_interval_limiter(
  10. min_interval_seconds: float,
  11. ) -> Callable[[], Awaitable[None]]:
  12. """返回 awaitable 限速函数:保证两次调用间隔不少于 min_interval_seconds。"""
  13. lock = threading.Lock()
  14. state = {"next_allowed": 0.0}
  15. async def _wait() -> None:
  16. with lock:
  17. now = time.monotonic()
  18. wait_seconds = state["next_allowed"] - now
  19. if wait_seconds < 0:
  20. wait_seconds = 0.0
  21. state["next_allowed"] = now + wait_seconds + float(min_interval_seconds)
  22. if wait_seconds > 0:
  23. await asyncio.sleep(wait_seconds)
  24. return _wait