Pull to refresh

Comments 7

Буферизированные каналы - в 95% пахнущий кусок кода, который требует убедительного обоснования

Можно читать и писать значения в массиве по индексам, если разные горутины используют разные индексы для этого.

Утверждение правильное, но я бы сказал, что опасное, особенно для новичков - надо очень хорошо понимать ref/spec и ref/mem чтобы знать, где можно (например, с доступом по индексам), а где нельзя (например, append)

Функции takeFirst и takeFirst2 в случаеlen(options) == 0 (допустимость этого варианта отмечена комментарием в коде) работать корректно не будут.
Там будет паника
all goroutines are asleep - deadlock! потому что цикл
for first := range ch { return first } будет вечным: в канал никто не пишет и он не закрыт.

Спасибо, согласен. Надо проверки добавить в начале функции и возвращать сразу nil, если аргументы пустые.

Вы бы хоть описали причину проблем, а не просто демонстрировали их. В итоге новичкам ничего не понятно, а для профи ничего нового.

Спасибо за обратную связь.

А можете подсказать, что вы имеете в виду под объяснением причин проблем? Я вроде постарался везде описать, что и почему происходит, не вдаваясь в подробности и не рассказывая то, что Go разработчики уже наверняка знают. Считаете, что стоило побольше углубиться или что-то иное?

Про профи не соглашусь - все проблемы и примеры взяты из реального опыта, где разработчики среднего уровня и выше писали примерно такой код, при этом не задумываясь "а что если контекст отменится прямо тут?" и "если я использую каналы тут, к каким проблемам это приведет?". Я бы назвал их профи, но некоторые просто не задумывались о таких потенциальных проблемах, а уж тесты на такое писать вообще не каждый любит. А уж писать тесты на случаи кроме happy path - в моем опыте совсем редкость.

Мне понравилась статья. Многое знакомо, а что-то - нет. Но хорошо, что информация теперь есть в одном месте.

Уберем первый select, и горутина может начать делать уже ненужную работу. Уберем второй - она может начать писать в канал, в то время как будет произведен выход из функции (контекст отменен или произошла паника). Уберем третий - горутина может начать читать из канала, в то время как одна или несколько горутин не записали значение в канал (контекст был отменен или в горутине произошла паника). Добавление всех трех select обеспечивает более корректную работу и, что может быть более важно, более корректное завершение работы всей функции.

В статье об этом не сказано, но я думаю это стоит упомянуть: работа внутри select происходит со случайным каналом. И если одновременно готов и ctx.Done() и какая-то запись в другой канал - то вполне вероятно, что сработает запись в канал, а не ctx.Done(). Для решения этого подводного камня есть свои способы. Поэтому реализацию работы с каналами надо выбирать под свои нужды.

Sign up to leave a comment.

Articles