Ответ вслух Middle Паттерны конкурентности обновлено

Спроектировать worker pool

Вопрос

Напишите вслух worker pool: N воркеров обрабатывают задачи из списка, результаты нужны в исходном порядке, первая ошибка должна остановить всё, есть общий таймаут.

Попробуйте сами

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

Показать ответ и разбор

Коротко

Создаю ctx, cancel := context.WithTimeout(parent, d) и группу g, ctx := errgroup.WithContext(ctx). Результаты храню в res := make([]Result, len(tasks)).

Что должно прозвучать в ответе

  • Контекст с таймаутом и отменой при первой ошибке (errgroup.WithContext или свой cancel)

  • Канал задач с индексами, N горутин читают его в цикле

  • Результат пишется по индексу в заранее созданный слайс

  • Отправка задач в select с ctx.Done, закрытие канала задач после отправки

  • Ожидание через WaitGroup или g.Wait, возврат первой ошибки

  • Проверка -race, тест на ошибку и таймаут

Что могут спросить следом

  • Что изменится, если задач бесконечный поток?
  • Как сделать retry с backoff для отдельных задач?

Разбор

Создаю ctx, cancel := context.WithTimeout(parent, d) и группу g, ctx := errgroup.WithContext(ctx). Результаты храню в res := make([]Result, len(tasks)). Канал jobs chan int с индексами. Запускаю N воркеров через g.Go: каждый в цикле читает индекс, обрабатывает tasks[i] с ctx и пишет res[i]; при ошибке возвращает её, errgroup отменит ctx, и остальные выйдут. Отдельной задачей в группе отправляю индексы: каждая отправка в select с ctx.Done(), после цикла close(jobs). Затем if err := g.Wait(); err != nil { return nil, err }. Порядок сохраняется за счёт индексов, гонки нет, потому что ячейки разные. Без errgroup то же самое на WaitGroup, sync.Once для первой ошибки и cancel. Для бесконечного потока вместо слайса результатов канал результатов и graceful остановка по ctx. Проверяю тестами под -race, включая сценарий с ошибкой в середине и истёкшим таймаутом.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.