default и nil-канал в select
Сброс статистики тормозил воркеров: они стояли в очереди, пока метрики уезжали в хранилище. Миша переделал отправку — если приёмник был занят, статистика оставалась ждать до следующей попытки, а обработка файлов шла дальше. Сергей прогнал стенд и подтвердил: задержки исчезли.
default делает select неблокирующим, а присваивание каналу nil выключает его ветку — так select превращается в гибкий коммутатор.
Default — неблокирующая проверка
select {
case f := <-queue:
fmt.Println("взял файл:", f)
default:
fmt.Println("в очереди пока пусто")
}
С default select не ждёт: если ни один case не готов, выполняется default. Это классическая неблокирующая проверка — «есть ли уже файл, и если нет, идём дальше».
Nil-канал выключает ветку
Операции на nil-канале блокируются навсегда. В select это свойство работает на нас: case с nil-каналом никогда не считается готовым, то есть просто выключен.
var paused chan struct{} // nil: ветка выключена
select {
case f := <-queue:
// ...
case <-paused: // не сработает, пока paused — nil
return
}
Присваивая каналу nil, можно динамически убирать ветки: например, «выключить» чтение очереди, пока конвейер переиндексируется.
Коммутатор
Вместе default и nil дают паттерн: горутина крутится в цикле, у неё есть постоянные ветки и переключаемые. Нужно временно не читать один из источников — присвоил nil; нужно неблокирующе опросить — default. Select из «ждалки» превращается в коммутатор событий конвейера.
Вы узнаете:
- как закрытый канал ведёт себя в select
- как идиома try-send работает через default
Проверьте себя
Как приостановить чтение из канала, не завершая select-цикл?
Зачем default в цикле-коммутаторе с несколькими источниками?
Что даёт select с default?
правильных ответов
default — не ждать; nil-канал — выключенная ветка. Select — гибкий инструмент маршрутизации событий.
10 000 ₽ · 60 минут · онлайн