Реализуйте пул воркеров, устойчивый к панике в пользовательских задачах. Если
задача fn() паникует, воркер должен восстановиться (recover), отправить
ошибку в канал errs и продолжить брать следующие задачи — пул не должен
падать.
type SafePool struct {
// ...
}
// NewSafePool создаёт пул из workers воркеров, читающих задачи из tasks.
// При панике в задаче ошибка отправляется в errs, а воркер продолжает работу.
func NewSafePool(workers int, tasks <-chan func(), errs chan<- error) *SafePool
// Start запускает воркеры.
func (p *SafePool) Start()
// Wait блокируется, пока канал tasks не опустеет и не будет закрыт,
// а все воркеры не завершатся.
func (p *SafePool) Wait()
Требования:
- Каждая задача выполняется через
recover-обёртку.
- При панике: ошибка отправляется в
errs, воркер берёт следующую задачу.
- Нормальные (не паникующие) задачи выполняются полностью.
Wait() корректно дожидается дренажа tasks и завершения всех воркеров.
- Число отправленных в
errs ошибок равно числу паникующих задач.
На что смотрит интервьюер:
- Корректное использование
defer/recover внутри цикла воркера (паника
одной задачи не «съедает» воркер).
- Воркер продолжает работу после восстановления.
- Отсутствие гонок под
-race, отсутствие утечек горутин.
- Точный учёт: все нормальные задачи выполнены, число ошибок == число паник.
- Аккуратная синхронизация завершения через
sync.WaitGroup.