Golang Дайджест
8.17K subscribers
39 photos
1 file
187 links
Самое интересное из мира Go: новости, статьи, проекты, сервисы, изменения в языке и др.

Посты публикуются не часто - только самое важное, с чем я лично ознакомился.

Поэтому можно не мьютить канал =)

Обратная связь: @justskiv
Download Telegram
#game4devs #concurrency

Если вы плохо понимаете проблемы параллельного программирования и конкурентного доступа, очень советую пройти игру - The Deadlock Empire.

Прохождение довольно интересное, быстро затягивает. Те кто осилит, на выходе будут хорошо понимать, почему и как параллельные процессы могут приводить к поломкам, как с этим бороться с помощью примитивов синхронизации и т.п.

Самое главное - вы поймёте, что безопасный параллельный код писать очень сложно, а порой даже невозможно (всегда будет оставаться маленькая вероятность фэйла, с которой придётся жить).

https://deadlockempire.github.io/
👍5🔥4🤔1
Как писать параллельный код - основы

https://habr.com/ru/companies/timeweb/articles/770912/

Очень хорошая статья, в которой простым языком на простеньких примерах рассказываются основы работы с параллельным кодом:

- Зачем это нужно
- Как и почему нельзя писать параллельный код
- Какие издержки распараллеливания мы имеем (спойлер - код становится намного сложнее и опасней)
и др.

Если вы не ещё сталкивались с подобными задачами, рекомендую ознакомиться.

#article #concurrency
👍20🔥5
Testing Time: тестируем асинхронный код без time.Sleep в Go 1.25

Пост про testing/synctest в официальном блоге разработчиков Go

- Оригинал
- Хороший перевод

Go Team наконец-то решили давнюю проблему тестирования конкурентного кода. В 1.24 вышел экспериментальный пакет testing/synctest, а в 1.25 он стал стабильным.

Очень краткая суть: запускаешь тест в "пузыре" с фейковым временем и ждёшь, пока все горутины станут "устойчиво заблокированными" — то есть могут быть разблокированы только другими горутинами из того же пузыря.

Проблема стара как мир:

- Тестируешь context.WithDeadline — либо ждёшь реальную секунду (медленно), либо не ждёшь достаточно (тест нестабилен, флапает)

- Добавляешь time.Sleep с запасом — тест тормозит

- Убираешь запас — тест падает на CI под нагрузкой

Классический выбор: slow or flaky, pick... one!

Решение — пузырь с двумя функциями:

- synctest.Test(t, func(t *testing.T) {...}) — запускает функцию в пузыре с фейковым временем

- synctest.Wait() — ждёт, пока все горутины в пузыре станут "durably blocked"

- Время идёт только когда все заблокированы, вычисления занимают 0 времени

- Начало эпохи: полночь 1 января 2000 UTC (как в Go Playground)

Пример до/после:
// Было: медленно и ненадёжно
time.Sleep(time.Until(deadline) + 100*time.Millisecond)

// Стало: быстро и стабильно
synctest.Test(t, func(t *testing.T) {
time.Sleep(time.Until(deadline))
synctest.Wait()
})


————

Мне понравилось, что автор также рассказывает про историю создания. Сначала пытались добавить поддержку тестирования прямо в http-пакет — не вышло, особенно с HTTP/2. Потом сделали грязный хак с парсингом runtime.Stack() — работало, но стыдно показать. В итоге добавили поддержку прямо в рантайм.

Из ограничений: не работает с реальной сетью (вместо этого нужно использовать их имитацию в памяти — in-memory fake), мьютексы не считаются durably blocking, syscalls и cgo тоже. Но для 95% кейсов — самое то.

Забавно, что самый первый пример в статье — тест для context.WithDeadline. Видимо, это была та самая боль, с которой всё началось 🙃

#go1_25 #go_official #testing #concurrency
Please open Telegram to view this post
VIEW IN TELEGRAM
11👍5🔥5
conc — удобные примитивы для конкурентного кода

https://github.com/sourcegraph/conc

⭐️ ~10.1k

Небольшая библиотека от Sourcegraph, которая предлагает более безопасные и удобные обёртки над стандартными инструментами конкурентности в Go.

Впервые встретил её на своей текущей работе, и в целом мне понравилось, поэтому грех не поделиться.

Что в ней есть интересного:

- conc.WaitGroup — альтернатива стандартному sync.WaitGroup: ловит паники в горутинах и возвращает их в Wait(), а также не даёт забыть вызвать Wait()

- pool — конкурентный пул задач с ограничением числа горутин (WithMaxGoroutines), сбором ошибок (WithErrors, WithFirstError) и отменой задач при ошибках (WithContext)

- stream — параллельное выполнение задач с сохранением порядка результатов (удобно, когда порядок важен, но хочется параллелизма)

- iter.Map / ForEach — упрощённые хелперы для конкурентной обработки слайсов

🟠 Библиотека пока pre-1.0 (последний релиз в феврале 2023), API может меняться.

#library #concurrency #goroutines
Please open Telegram to view this post
VIEW IN TELEGRAM
14👍11🤯1
🔍 Утечка горутин в продакшене — разбор реального кейса

- Оригинальный пост
- Обсуждение на Hacker News

Автор рассказывает про классическую production-проблему: out of memory в k8s-подах посреди во время работы сервиса.
Спойлер: виноваты горутины, которые живут вечно.

Как искали проблему:

- Grafana показала растущее потребление памяти горутинами
- Подключили pprof и какое-то время мониторили результаты
- Нашли фабрику бесконечных горутин 🙃

Виновник — функция конвертации канала:

func ToDoneInterface(done <-chan struct{}) <-chan interface{} {
interfaceStream := make(chan interface{})
go func() {
defer close(interfaceStream)
select {
case <-done: return
}
}()
return interfaceStream
}


Проблема: select{} ждёт сигнала из done, но если контекст никогда не отменяется — горутина блокируется навсегда. defer close() там есть, но он не поможет, если select никогда не вернётся.

Инструменты для поиска утечек:

- Grafana + Pyroscope — flame-графы памяти
- pprof с diff_base — сравнение снапшотов до/после
- goleak — для автоматического обнаружения в тестах

Главная мысль от автора: не конвертируйте каналы!
Используйте обычные паттерны работы с context.Context и не забывайте вызывать .Done() там, где нужно.

————

Что ж, вот вам ещё одно напоминание о том, что Go хоть и простой язык, но конкурентность в нём кусается как везде. И go func() — это не fire-and-forget, как кажется новичкам, а обязательство следить за временем жизни горутины. Опытный разработчик 10 раз подумает перед тем как использовать эту конструкцию где бы то ни было.

#article #concurrency #english
Please open Telegram to view this post
VIEW IN TELEGRAM
👍206🔥3