В коде есть опасный Unlock без показанного Lock, повторное закрытие канала и гонка с отправителями. Cancel не прерывает произвольную задачу немедленно.
func (p *Pool) Stop() {
В коде есть опасный Unlock без показанного Lock, повторное закрытие канала и гонка с отправителями. Cancel не прерывает произвольную задачу немедленно.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
func (p *Pool) Stop() { p.mu.Unlock()
// Теперь можно безопасно закрыть канал
close(p.tasks) // сигнал воркерам: новых задач не будет, дочитайте остаток
p.wg.Wait() // ждём завершения всех горутин
p.cancel() // отменяем контекст на всякий случай
fmt.Println("Pool stopped.")
}
// ForceStop принудительно останавливает все воркеры без ожидания завершения задач. // Воркеры будут прерваны немедленно через контекст. func (p *Pool) ForceStop(timeout time.Duration) { fmt.Printf("Force stopping pool (timeout: %v)...\n", timeout)
// Блокируем добавление новых задач
p.mu.Lock()
p.isOpen = false
p.mu.Unlock()
// Закрываем канал, чтобы воркеры не брали новые задачи
close(p.tasks)
// Отменяем контекст – это прервет все выполняющиеся задачи
p.cancel()
// Даём ограниченное время на завершение
done := make(chan struct{})
go func() {
p.wg.Wait()
close(done)
}()
select {
case <-done:
fmt.Println("Pool force stopped (все воркеры завершены)")
case <-time.After(timeout):
fmt.Println("Pool force stopped (timeout, могут остаться зависшие горутины)")
}
}
Ответ
В коде есть опасный Unlock без показанного Lock, повторное закрытие канала и гонка с отправителями. Cancel не прерывает произвольную задачу немедленно.
Остановка должна быть идемпотентной: запретить новые отправки, согласованно дождаться активных отправителей, закрыть tasks один раз и дождаться workers. При принудительной остановке сначала сигнализируйте отмену; сами задачи должны её проверять. Закрытый буферизированный канал продолжает отдавать остаток. Timeout ограничивает ожидание вызывающего кода, но не убивает зависшие горутины. Полная правка требует кода Submit и worker.