Context Cancellation - это не kill -9 — 22 апреля 2026 г. в 17:18:27.294
Context Cancellation - это не kill -9 Одна из самых частых иллюзий у разработчиков, приходящих в Go: "Я вызвал cancel(), почему моя горутина всё еще работает?" Важно запомнить: В Go нельзя принудительно убить горутину снаружи. Нет никакого PID, по которому можно стрельнуть сигналом. context в Go реализует кооперативную отмену. Это значит, что cancel() - это не приказ "Умри!", а вежливое сообщение: "Брат, ты нам больше не нужен, сворачивайся, как сможешь". Если ваша горутина не проверяет этот канал, она будет молотить до победного конца (или до паники), даже если клиент давно отвалился по таймауту. ❌ Как делать НЕ надо (Игнорирование) func HeavyWork(ctx context.Context) { // Мы передали контекст, но... не используем его for i := 0; i < 1000000; i++ { calculateHash(i) // Жжёт CPU впустую, если ctx отменен } } ✅ Как надо (Проверка канала) В любом долгом цикле или блокирующей операции вы обязаны слушать ctx.Done(). func HeavyWork(ctx context.Context) error { for i := 0; i < 1000000; i++ { // Вариант 1: Неблокирующая проверка в каждой итерации select { case <-ctx.Done(): return ctx.Err() // "context canceled" или "deadline exceeded" default: // Работаем дальше } calculateHash(i) } return nil } Нюанс для Сеньоров: context.Cause (Go 1.20+) Раньше, получая ctx.Err(), мы видели просто context canceled. Это неинформативно. Кто отменил? Почему? Начиная с Go 1.20, используйте WithCancelCause: ctx, cancel := context.WithCancelCause(parent) // Где-то в логике отмены: cancel(fmt.Errorf("client disconnect inside handler")) // В горутине: if ctx.Err() != nil { fmt.Println(context.Cause(ctx)) // Печатает конкретную причину! } ☝️Context - это кровеносная система вашего приложения. Если вы пишете функцию, которая делает что-то дольше 10мс или ходит в сеть/базу - всегда принимайте первым аргументом ctx и всегда прокидывайте его дальше. Библиотеки (pgx, net/http) уже умеют его слушать, просто дайте им этот шанс. Не плодите горутины-зомби. 🧟♂️ #golang #context #concurrency #bestpractices 👉 @golang_lib

