горутину-генератор, возвращает два канала с данными и ошибками. Есть функция-горутина B, которая принимает контекст. Настройка пайплайна происходит в третьей функции main. Как сделать так, чтобы при возникновении ошибки в A все горутины B отменились? (В каком месте надо писать ctx.WithCancel ?)
Имхо в мэйне. Мэйн же читает из канала A.errors? При получении ошибки, отменять контекст.
Ну тут все зависит. Если в А происходит ошибка, то после записи в канал с ошибками, она закрывает оба канала? И с данными и с ошибками?
Тогда нужно еще передавать cancel в A?
Не обязательно. Можно отменить его в Main. После того как сработает <- A.errors
А, точно. Функция A да, завершается и закрывает все каналы при ошибке
Ну вот. Следовательно в функции B канал с данными тоже окажется закрыт. Нужен ли в таком случае контекст вообще? Или достаточно обработать последний элемент данных, и на следующей итерации обнаружить канал с данными закрытым и завершиться
В таком случае B которая обрабатывает данные, вообще не переживает по какой причине канал закрыт - закончились данные, или из-за ошибки. Ее задача обрабатывать данные пока канал с данными не закрыт. В свою очередь Main горутина является супервизором, и может зарепортить об ошибке, в producer’е через A.errors
Ну это как пример. Как общая рекомендация я бы избегал сложных и хитрых отмен контекста непонятно где. Очень сложно потом понять, что произошло и вообще читать такой код. Лучше всем таким заниматься в Main. Кмк
А вообще, какая общая рекомендация, если есть k-уровневый пайплайн, функция main, ошибка на любом уровне влечет за собой отмену всей функции main?
Не могу сказать, я таких пайплайнов не писал у меня обычно максимум один продьюсер и 1:N консьюмеров. Надо конкретные примеры смотреть
в мейне. Контекст передаешь и в А и в B, если в А ошибка, то в ней вызывается cancel, который завершает все горутины в B
Типо передавать cancel в A?
если ты создаешь контекст внутри функции А, то ты не закроешь что-то снаружи функции А Можно не передавать, а ждать, если А вернет ошибку, то делать cancel
Спасибо) Я в итоге сделал через ErrGroup
Обсуждают сегодня