Асинхронная отправка тысяч запросов с ограничением скорости 10 запросов в секунду

Нужны два независимых ограничения: семафор на 10 активных запросов и ограничитель стартов до 10 за скользящую секунду. Один semaphore не задаёт requests per second.

Короткий ответ

Что ответить на собеседовании

Нужны два независимых ограничения: семафор на 10 активных запросов и ограничитель стартов до 10 за скользящую секунду. Один semaphore не задаёт requests per second.

Подробный разбор

Ответ с пояснениями

Условие

Разработайте асинхронную функцию do_requests на базе asyncio, которая будет выполнять около 1000 GET‑запросов к разным ресурсам. Параллельно не должно работать более 10 запросов, т.е. необходимо реализовать ограничитель количества одновременно активных запросов. Каждый запрос отличается только уникальным URL, а полученный ответ следует вывести в консоль. Учтите, что внешний сервис отклонит запросы, если их количество превысит 10 в секунду.

async def do_requests(urls: list[str]) -> None:

Ответ

Нужны два независимых ограничения: семафор на 10 активных запросов и ограничитель стартов до 10 за скользящую секунду. Один semaphore не задаёт requests per second.

Пример ядра ограничителя стартов:

import asyncio
from collections import deque

class RateGate:
    def __init__(self):
        self.starts = deque()
        self.lock = asyncio.Lock()

    async def wait(self):
        async with self.lock:
            loop = asyncio.get_running_loop()
            while True:
                now = loop.time()
                while self.starts and self.starts[0] <= now - 1:
                    self.starts.popleft()
                if len(self.starts) < 10:
                    self.starts.append(now)
                    return
                await asyncio.sleep(self.starts[0] + 1 - now)

В do_requests создайте общий async HTTP-клиент, gate и semaphore. Каждый worker сначала получает semaphore, затем ждёт gate, выполняет GET с timeout и печатает проверенный ответ. Для тысячи URL лучше ограниченная очередь workers, чем неограниченный запуск. Повторные запросы тоже проходят gate; серверный 429 и Retry-After обрабатываются отдельно. Лимит локальный для одного процесса.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее