В представленном коде используется asyncio.Semaphore для ограничения количества одновременно выполняемых асинхронных запросов к API (через aiohttp). Это предотвращает перегрузку сервера или клиента.
Ограничение API-запросов через asyncio.Semaphore
В представленном коде используется asyncio.Semaphore для ограничения количества одновременно выполняемых асинхронных запросов к API (через aiohttp). Это предотвращает перегрузку сервера или клиента.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
В службе технической поддержки заявки (тикеты) могут порождать подзаявки.
Система логирует каждое действие: открытие или закрытие тикета. События поступают в хронологическом порядке.
Важно проверить, что последовательность событий корректна:
Нельзя закрыть тикет, который не был открыт.
Нельзя открыть уже открытый тикет (его ID уже присутствует среди открытых).
Закрытие должно происходить в порядке, обратном открытию (вложенность): последний открытый тикет должен быть закрыт первым.
Реализовать функцию, которая принимает список событий (каждый элемент — словарь с ключами 'type' ('open' или 'close') и 'ticket_id').
Примеры:
[
{'type': 'open', 'ticket_id': 'A'},
{'type': 'open', 'ticket_id': 'B'},
{'type': 'close', 'ticket_id': 'B'},
{'type': 'close', 'ticket_id': 'A'}
]
результат True
[
{'type': 'open', 'ticket_id': 'A'},
{'type': 'close', 'ticket_id': 'B'}
]
Результат False.
Ответ
В представленном коде используется asyncio.Semaphore для ограничения количества одновременно выполняемых асинхронных запросов к API (через aiohttp). Это предотвращает перегрузку сервера или клиента.
Основная идея:
- Создаётся семафор с максимальным числом одновременных запросов
max_concurrent_requests. - Для каждого
ticket_idсоздаётся задача_get_ticket, которая внутри должна использовать семафор (черезasync with semaphore:), чтобы ограничить параллелизм. - Все задачи запускаются одновременно, но семафор гарантирует, что не более
max_concurrent_requestsвыполняются одновременно. - Результаты собираются последовательно через
await task.
Пример использования семафора внутри _get_ticket:
async def _get_ticket(self, ticket_id, session, semaphore):
async with semaphore:
async with session.get(f'https://api.example.com/tickets/{ticket_id}') as resp:
if resp.status == 200:
return await resp.json()
return None
Такой подход позволяет эффективно и безопасно делать множество запросов, не превышая лимиты сервера и не создавая слишком много одновременных соединений.