Asyncio TaskGroup: обработка ошибок параллельного опроса

Напишите решение на Python и проверьте его на странице.

Другие упражнения по этой теме: Asyncio TaskGroup и gather: задачи на ошибки и отмену корутин.

Зондирование сетевых узлов

Анализатор сетевого контура проверяет доступность внешних ресурсов, запуская параллельные задачи зондирования внутри asyncio.TaskGroup. Каждый узел опрашивается отдельной корутиной, и во время массовой проверки поведение системы зависит от характера возникших неполадок.

По регламенту мониторинга сетевые ошибки соединения — любые подклассы ConnectionError — считаются штатным и ожидаемым отказом отдельного узла. Корутина должна перехватить такой сбой внутри себя, не выпуская его на уровень группы, и вернуть статус недоступности ресурса. Благодаря этому контекст TaskGroup сохраняется, а остальные задачи продолжают опрос соседних узлов без помех.

Если же любая из корутин встречает непредвиденную системную ошибку, вроде RuntimeError, исключение не должно перехватываться на месте. В этом случае TaskGroup каскадно отменяет остальные проверки и выбрасывает ExceptionGroup.

Реализуйте функцию распределённого зондирования узлов, которая изолирует ожидаемые сетевые ошибки до уровня группы, но гарантирует немедленную отмену всех задач при критическом системном сбое.

Что уже дано

В редакторе объявлена асинхронная функция-заглушка probe_nodes(nodes, check, group).

Вспомогательные классы и функции для эмуляции узлов и групп задач уже доступны при выполнении, реализовывать их самостоятельно не требуется.

Что нужно сделать

Реализуйте асинхронную функцию probe_nodes(nodes, check, group).

Функция принимает три аргумента:

  • nodes — список (или наследник списка) токенов узлов длиной от 0 до 100 элементов;
  • check — асинхронная функция check(node), опрашивающая переданный узел;
  • group — предоставленный свежий экземпляр asyncio.TaskGroup (или его реального подкласса).

Правила проверки узлов:

  • Войдите в контекст предоставленной группы group через async with group: и создайте по одной дочерней задаче для каждого узла с помощью метода group.create_task(...). Заменять переданный экземпляр группы или подменять его на asyncio.gather запрещено.
  • Каждый токен из nodes передаётся в check ровно один раз без изменений.
  • Все дочерние проверки должны запускаться конкурентно.
  • Внутри каждой дочерней корутины изолируйте сетевые сбои: если вызов check(node) возбуждает ConnectionError или любой его подкласс, корутина фиксирует статус узла как False. При успешном завершении check(node) (независимо от возвращённого значения) статус узла считается True.
  • Любые другие обычные исключения (например, системные ошибки вроде RuntimeError) не должны перехватываться внутри дочерней задачи. Они выходят наружу в TaskGroup, вызывая каскадную отмену остальных дочерних задач и выброс ExceptionGroup при выходе из контекста группы.
  • Внешняя отмена всей операции зондирования должна штатно распространять asyncio.CancelledError и останавливать дочерние задачи. Её нельзя перехватывать под видом сетевой ошибки или оставлять висящие фоновые задачи.
  • Повторные попытки опроса узлов реализовывать не нужно.
  • После успешного завершения всех задач группы функция возвращает список булевых статусов доступности (True или False), строго соответствующий исходному порядку элементов в nodes. Если список nodes пуст, верните пустой список [].

Ввод и вывод

Стандартные потоки ввода stdin и вывода stdout в решении не используются: считывать ввод и вызывать print() не нужно. После выполнения кода учащегося проверяющая система считывает из пространства имён модуля функцию верхнего уровня probe_nodes и вызывает её с проверочными аргументами.

Пример использования

import asyncio
async def check(node):
    await asyncio.sleep(0)
    if node == "offline":
        raise ConnectionResetError("unavailable")
print(asyncio.run(probe_nodes(["online", "offline"], check, asyncio.TaskGroup())))

Вывод:

[True, False]
РешениеPython

Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.

Отправьте решение, чтобы увидеть результаты тестов.

Связанные задачи