Какая проблема возникает, если задача не закрыта в Go?
Что проверяют
Понимаете ли вы, что горутину нельзя убить снаружи и что зависшая горутина никогда не будет собрана сборщиком мусора. Следом обычно просят показать, как вы находите утечку горутин в работающем сервисе и как пишете код, в котором её нет.
Как отвечать
Незавершённая горутина это утечка. Она держит свой стек (стартует с 2 КБ и растёт) и всё, на что ссылается: буферы, соединения, крупные структуры. Сборщик мусора горутины не завершает, поэтому память и число горутин растут, пока сервис не упрётся в лимит контейнера.
Типичные причины:
- блокировка на канале: горутина пишет в небуферизованный канал, а читатель уже ушёл, например по таймауту. Или
for v := range chждёт вечно, потому что отправитель не вызвалclose(ch); - нет сигнала остановки: воркер крутит бесконечный цикл и не проверяет
ctx.Done(); - забытый cancel:
context.WithTimeoutбезdefer cancel()держит ресурсы до срабатывания таймера.go vetловит это проверкойlostcancel; - незакрытые ресурсы: не вызван
resp.Body.Close(), и HTTP-соединение не возвращается в пул.
Как защищаться: у каждой горутины должен быть владелец и способ её остановить. Передавайте context.Context и выходите по case <-ctx.Done() в select, закрывайте канал на стороне отправителя, ждите завершения через sync.WaitGroup или errgroup.Group, который ещё и отменяет контекст при первой ошибке. Если результат может не понадобиться, делайте канал с буфером на одно значение, чтобы отправитель не завис.
Диагностика: runtime.NumGoroutine() в метриках, профиль /debug/pprof/goroutine?debug=2, где видно, на какой строке висят тысячи одинаковых горутин, и goleak в тестах.
Где спотыкаются
Говорят, что context отменяет горутину. Контекст только сообщает об отмене: если код не проверяет ctx.Done(), горутина продолжит работать.
Закрывают канал со стороны читателя или закрывают его дважды. Оба варианта заканчиваются паникой: при следующей записи в закрытый канал или при повторном close.
Ищут утечку только в профиле кучи. Он покажет, где выделена память, но не то, что её держат тысячи зависших горутин. Причина видна в профиле горутин и в графике их числа во времени.