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]
Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.
Отправьте решение, чтобы увидеть результаты тестов.
Связанные задачи
- Asyncio TaskGroup и gather: что происходит при ошибке корутины
- Asyncio TaskGroup: сбор результатов с отменёнными задачами
- Asyncio gather: отмена оставшихся задач при ошибке
- Asyncio TaskGroup: двухфазная проверка и публикация конфигурации
- Asyncio gather и TaskGroup: соберите исключения конкурентных задач
- Удаление ключа из ChainMap в Python: проверка поведения del
