tgoop.com/golang_lib/465
Create:
Last Update:
Last Update:
🧠 Почему context.WithCancel
может вызвать утечку goroutinecontext.WithCancel
— удобный способ завершать операции, но если не вызывать cancel()
, вы получите утечку. Причём не всегда это очевидно.
Посмотрим:
func handler(w http.ResponseWriter, r *http.Request) {
ctx, cancel := context.WithCancel(r.Context())
// cancel не вызывается!
go doSomething(ctx)
w.Write([]byte("done"))
}
func doSomething(ctx context.Context) {
select {
case <-time.After(10 * time.Second):
fmt.Println("done work")
case <-ctx.Done():
fmt.Println("canceled")
}
}
Что здесь не так?
Если
handler
завершится раньше, чем doSomething
, и cancel()
не вызван — doSomething
останется висеть, пока не истечёт r.Context()
или time.After
. И таких горутин может накопиться много, особенно при высоких нагрузках.💡 Как избежать
1. Всегда вызывай
cancel()
, когда используешь context.WithCancel
, даже если кажется, что это «не нужно».
ctx, cancel := context.WithCancel(r.Context())
defer cancel()
2. Если передаёшь контекст в goroutine — убедись, что она завершится, даже если вызывающая функция ушла.
context.WithCancel
— мощный инструмент. Но без вызова cancel()
ты легко создашь утечку, которую не поймаешь ни в логах, ни в профилях — только под нагрузкой.👉 @golang_lib
BY Библиотека Go (Golang) разработчика

Share with your friend now:
tgoop.com/golang_lib/465