返回 douyin-downloader
rate_limiter.py
根目录 / control / rate_limiter.py
1 import asyncio
2 import random
3 import time
4
5
6 class RateLimiter:
7 def __init__(self, max_per_second: float = 2):
8 if max_per_second <= 0:
9 max_per_second = 2
10 self.max_per_second = max_per_second
11 self.min_interval = 1.0 / max_per_second
12 self.last_request = 0.0
13 self._lock = asyncio.Lock()
14
15 async def acquire(self):
16 async with self._lock:
17 current = time.time()
18 time_since_last = current - self.last_request
19
20 if time_since_last < self.min_interval:
21 wait_time = self.min_interval - time_since_last
22 await asyncio.sleep(wait_time)
23
24 # Jitter must run inside the lock so that the next caller waits
25 # min_interval since the actual fire time, not since the prior
26 # caller acquired the lock.
27 await asyncio.sleep(random.uniform(0, 0.5))
28 self.last_request = time.time()
29
29 lines PYTHON