Media is too big
VIEW IN TELEGRAM
Паттерн Outbox - теория и практика | Архитектура Микросервисов
Transactional Outbox - паттерн, который обеспечивает атомарность двух операций - сохранения измений в БД и отправки сообщения об этих изменениях в другой сервис.
В этом видео мы подробно разберемся, почему решаемая им проблема важна, как он устроен, а затем реализуем его самостоятельно на языке Go
00:00 Какую проблему мы решаем
05:47 Нам нужна атомарность
07:03 Про Two-Phase Commit
07:36 NoSQL базы данных
09:59 Гарантия доставки - "At Least Once"
11:48 Практика: пишем Outbox для сокращателя ссылок
12:43 Storage: сохраняем сообщения в таблицу
28:01 Event Sender: отправка сообщений из таблицы
36:52 Подключаем Event Sender
39:09 Тестируем отправку сообщений
41:12 Итоги
42:07 Мой Телеграм-канал: почему он важен
43:05 Заключение
источник
👉 @golang_lib
Transactional Outbox - паттерн, который обеспечивает атомарность двух операций - сохранения измений в БД и отправки сообщения об этих изменениях в другой сервис.
В этом видео мы подробно разберемся, почему решаемая им проблема важна, как он устроен, а затем реализуем его самостоятельно на языке Go
00:00 Какую проблему мы решаем
05:47 Нам нужна атомарность
07:03 Про Two-Phase Commit
07:36 NoSQL базы данных
09:59 Гарантия доставки - "At Least Once"
11:48 Практика: пишем Outbox для сокращателя ссылок
12:43 Storage: сохраняем сообщения в таблицу
28:01 Event Sender: отправка сообщений из таблицы
36:52 Подключаем Event Sender
39:09 Тестируем отправку сообщений
41:12 Итоги
42:07 Мой Телеграм-канал: почему он важен
43:05 Заключение
источник
👉 @golang_lib
This media is not supported in your browser
VIEW IN TELEGRAM
Goschedviz — Визуализация работы планировщика Go
Инструмент для визуализации работы планировщика Go в терминале. Помогает понять поведение планировщика Go через отображение метрик в реальном времени.
⚠️ Важно: Этот инструмент предназначен только для образовательных целей. Он разработан для помощи в понимании работы планировщика Go и не должен использоваться в продакшен-окружении или критически важных проектах. В нём могут быть ошибки и он не оптимизирован для производительности.
Возможности
🔹Мониторинг метрик планировщика Go в реальном времени с использованием GODEBUG schedtrace
🔹Мониторинг количества горутин через runtime метрики
🔹Консольный интерфейс с несколькими виджетами:
🔹Таблица текущих значений планировщика
🔹Диаграммы локальных очередей (LRQ)
🔹Индикаторы для GRQ, горутин, потоков и простаивающих процессоров
🔹Два графика истории (линейная и логарифмическая шкалы)
🔹Цветовая легенда метрик
🔹Поддержка мониторинга любой Go-программы
https://github.com/JustSkiv/goschedviz/blob/main/docs/README.ru.md
👉 @golang_lib
Инструмент для визуализации работы планировщика Go в терминале. Помогает понять поведение планировщика Go через отображение метрик в реальном времени.
⚠️ Важно: Этот инструмент предназначен только для образовательных целей. Он разработан для помощи в понимании работы планировщика Go и не должен использоваться в продакшен-окружении или критически важных проектах. В нём могут быть ошибки и он не оптимизирован для производительности.
Возможности
🔹Мониторинг метрик планировщика Go в реальном времени с использованием GODEBUG schedtrace
🔹Мониторинг количества горутин через runtime метрики
🔹Консольный интерфейс с несколькими виджетами:
🔹Таблица текущих значений планировщика
🔹Диаграммы локальных очередей (LRQ)
🔹Индикаторы для GRQ, горутин, потоков и простаивающих процессоров
🔹Два графика истории (линейная и логарифмическая шкалы)
🔹Цветовая легенда метрик
🔹Поддержка мониторинга любой Go-программы
https://github.com/JustSkiv/goschedviz/blob/main/docs/README.ru.md
👉 @golang_lib
Как работает автоматическое переключение на резервный сервер в случае сбоя основного?
Разберем концепцию высокой доступности баз данных и автоматического failover на практике
Приглашаем на открытый практический урок «Отказоустойчивый кластер Patroni» в рамках курса PostgreSQL для администраторов баз данных и разработчиков
✅ Практика: настройка кластер Patroni, включая конфигурацию DCS, настройку PostgreSQL и HAProxy.
Освойте основные команды Patroni для управления кластером, такие как переключение ролей, перезагрузка, реинициализация и настройка синхронной репликации.
Навыки полученные на уроке позволят создать отказоустойчивые решения для своих баз данных и эффективно администрировать отказоустойчивые кластеры PostgreSQL.
👉 Регистрация и подробности:
https://vk.cc/cJxU84
Разберем концепцию высокой доступности баз данных и автоматического failover на практике
Приглашаем на открытый практический урок «Отказоустойчивый кластер Patroni» в рамках курса PostgreSQL для администраторов баз данных и разработчиков
✅ Практика: настройка кластер Patroni, включая конфигурацию DCS, настройку PostgreSQL и HAProxy.
Освойте основные команды Patroni для управления кластером, такие как переключение ролей, перезагрузка, реинициализация и настройка синхронной репликации.
Навыки полученные на уроке позволят создать отказоустойчивые решения для своих баз данных и эффективно администрировать отказоустойчивые кластеры PostgreSQL.
👉 Регистрация и подробности:
https://vk.cc/cJxU84
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Aqua
Декларативный менеджер версий CLI, написанный на Go. Поддерживает лэйзи установку, реестр и непрерывное обновление с помощью Renovate. Версия CLI переключается бесшовно.
https://github.com/aquaproj/aqua
Demo https://asciinema.org/a/498262?autoplay=1
👉 @golang_lib
Декларативный менеджер версий CLI, написанный на Go. Поддерживает лэйзи установку, реестр и непрерывное обновление с помощью Renovate. Версия CLI переключается бесшовно.
https://github.com/aquaproj/aqua
Demo https://asciinema.org/a/498262?autoplay=1
👉 @golang_lib
This media is not supported in your browser
VIEW IN TELEGRAM
Просмотрщик сборок и исходного кода Go
Установка производится с помощью обычных команд Go:
Для Linux может потребоваться добавление некоторых дополнительных зависимостей. Чтобы не собирать версию Wayland или X11, можно использовать
Для запуска программы задайте фильтр регулярных выражений для проверяемой функции. -watch позволяет автоматически перезагружать исполняемый файл и информацию при его изменении.
https://github.com/loov/lensm
👉 @golang_lib
Установка производится с помощью обычных команд Go:
go install loov.dev/lensm@main
Для Linux может потребоваться добавление некоторых дополнительных зависимостей. Чтобы не собирать версию Wayland или X11, можно использовать
go install --tags nowayland loov.dev/lensm@main
или go install --tags nox11 loov.dev/lensm@main
соответственно.Для запуска программы задайте фильтр регулярных выражений для проверяемой функции. -watch позволяет автоматически перезагружать исполняемый файл и информацию при его изменении.
lensm -watch -filter Fibonacci lensm
https://github.com/loov/lensm
👉 @golang_lib
💔 Ваша backend-разработка уже не та?
😔 Микросервисы плохо масштабируются, API перегружены, а REST уже не справляется?
🚀 Решение есть – gRPC! Быстрое и эффективное взаимодействие сервисов без лишних накладных расходов.
Как освоить? 18 марта в 20:00 на открытом вебинаре разберем gRPC, Protocol Buffers, совместимость API и создание серверов.
➡️ Запишитесь сейчас и 🎁 получите скидку на большое обучение «Golang Developer. Professional»: https://vk.cc/cJGVFr
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
😔 Микросервисы плохо масштабируются, API перегружены, а REST уже не справляется?
🚀 Решение есть – gRPC! Быстрое и эффективное взаимодействие сервисов без лишних накладных расходов.
Как освоить? 18 марта в 20:00 на открытом вебинаре разберем gRPC, Protocol Buffers, совместимость API и создание серверов.
➡️ Запишитесь сейчас и 🎁 получите скидку на большое обучение «Golang Developer. Professional»: https://vk.cc/cJGVFr
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Планировщик Go — самый подробный гайд простым языком
Давайте спроектируем с нуля планировщик Go — начнём с самой простой и понятной наивной реализации, а затем шаг за шагом будем разбираться, какие изъяны в ней есть, и придумывать как их решать, постепенно усложняя общую модель.
Это один из лучших способов понять сложную систему или концепцию — пройти путь её поэтапного проектирования. Система сложна, осознать её очень непросто, но мы разобьём её на простые шаги, понять которые очень легко. После этого пазл сам собой сложится в голове, и общая картина системы будет для вас такой же простой и очевидной.
https://habr.com/ru/articles/891426/
👉 @golang_lib
Давайте спроектируем с нуля планировщик Go — начнём с самой простой и понятной наивной реализации, а затем шаг за шагом будем разбираться, какие изъяны в ней есть, и придумывать как их решать, постепенно усложняя общую модель.
Это один из лучших способов понять сложную систему или концепцию — пройти путь её поэтапного проектирования. Система сложна, осознать её очень непросто, но мы разобьём её на простые шаги, понять которые очень легко. После этого пазл сам собой сложится в голове, и общая картина системы будет для вас такой же простой и очевидной.
https://habr.com/ru/articles/891426/
👉 @golang_lib
Gotify/server
Простой сервер для отправки и получения сообщений в реальном времени по WebSocket. (Включает элегантный web-ui)
Нам нужен был простой сервер для отправки и получения сообщений (в реальном времени по WebSocket). Для этого существовало не так много проектов с открытым исходным кодом, а большинство существующих были заброшены. Также одним из требований была возможность самостоятельного хостинга. Мы знаем, что существует множество бесплатных и коммерческих push-сервисов.
Фичи
отправка сообщений через REST-API
принимать сообщения через WebSocket
управление пользователями, клиентами и приложениями
Плагины
Web-UI -> ./ui
CLI для отправки сообщений -> gotify/cli
Android-приложение -> gotify/android
https://github.com/gotify/server
👉 @golang_lib
Простой сервер для отправки и получения сообщений в реальном времени по WebSocket. (Включает элегантный web-ui)
Нам нужен был простой сервер для отправки и получения сообщений (в реальном времени по WebSocket). Для этого существовало не так много проектов с открытым исходным кодом, а большинство существующих были заброшены. Также одним из требований была возможность самостоятельного хостинга. Мы знаем, что существует множество бесплатных и коммерческих push-сервисов.
Фичи
отправка сообщений через REST-API
принимать сообщения через WebSocket
управление пользователями, клиентами и приложениями
Плагины
Web-UI -> ./ui
CLI для отправки сообщений -> gotify/cli
Android-приложение -> gotify/android
https://github.com/gotify/server
👉 @golang_lib
💼 Хотите прокачаться в Go и расширить карьерные перспективы?
🚀Go — это скорость, производительность и надежность. Компании всё чаще выбирают его для своих проектов, а спрос на разработчиков стремительно растёт.
На курсе «Golang Developer. Professional» вы:
— Разберетесь в идиоматике Go и освоите продвинутые инструменты.
— Поработаете с реальными коммерческими задачами.
— Изучите алгоритмы и подходы, которые ценят ведущие IT-компании.
— Получите удостоверение о повышении квалификации.
🏆 Вы сможете разрабатывать высоконагруженные серверные приложения, работать с SQL и NoSQL, а главное — претендовать на позиции Middle и Senior.
👨💻 Пройдите вступительное тестирование и получите скидку до 15% по промокоду: GO_03 на обучение: https://vk.cc/cJUSou
🚀Go — это скорость, производительность и надежность. Компании всё чаще выбирают его для своих проектов, а спрос на разработчиков стремительно растёт.
На курсе «Golang Developer. Professional» вы:
— Разберетесь в идиоматике Go и освоите продвинутые инструменты.
— Поработаете с реальными коммерческими задачами.
— Изучите алгоритмы и подходы, которые ценят ведущие IT-компании.
— Получите удостоверение о повышении квалификации.
🏆 Вы сможете разрабатывать высоконагруженные серверные приложения, работать с SQL и NoSQL, а главное — претендовать на позиции Middle и Senior.
👨💻 Пройдите вступительное тестирование и получите скидку до 15% по промокоду: GO_03 на обучение: https://vk.cc/cJUSou
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Ужасно подробные ошибки в API: пишем на Go инструмент для работы с ними
Меня зовут Александр Лырчиков, я разрабатываю систему хранения данных TATLIN.UNIFIED в YADRO. СХД — сложная система, и, если при работе произошла ошибка, она должна своевременно и понятно сообщать пользователю об этом. В большинстве веб-сервисов для этого используют баннер с надписью «Что-то пошло не так», но такой способ уведомления нам не подходит.
Мы столкнулись с проблемой, когда переданных сообщений и HTTP-кодов уже не хватает. Поэтому разработали собственный инструмент для обработки ошибок Terror (TATLIN + error). В результате работа с кодом стала проще, мы получили красивый API, а пользователи — понятное описание ошибки и локализацию текста на разные языки. В этой статье расскажу, как мы создавали Terror, чтобы вы смогли повторить решение.
https://habr.com/ru/companies/yadro/articles/817719/
👉 @golang_lib
Меня зовут Александр Лырчиков, я разрабатываю систему хранения данных TATLIN.UNIFIED в YADRO. СХД — сложная система, и, если при работе произошла ошибка, она должна своевременно и понятно сообщать пользователю об этом. В большинстве веб-сервисов для этого используют баннер с надписью «Что-то пошло не так», но такой способ уведомления нам не подходит.
Мы столкнулись с проблемой, когда переданных сообщений и HTTP-кодов уже не хватает. Поэтому разработали собственный инструмент для обработки ошибок Terror (TATLIN + error). В результате работа с кодом стала проще, мы получили красивый API, а пользователи — понятное описание ошибки и локализацию текста на разные языки. В этой статье расскажу, как мы создавали Terror, чтобы вы смогли повторить решение.
https://habr.com/ru/companies/yadro/articles/817719/
👉 @golang_lib
🧵 Три способа использовать каналы в Go
Каналы в Go — мощный инструмент для взаимодействия между горутинами. Рассмотрим три идиоматичных способа их использования:
1. Fan-out (расщепление задач)
Fan-out — это когда несколько воркеров читают из одного канала задач. Это позволяет обрабатывать задачи параллельно:
Задачи отправляются в
2. Fan-in (агрегация результатов)
Fan-in — это сбор результатов от нескольких источников в один канал. Используется, когда у нас несколько генераторов данных:
Мы слушаем оба канала и всё складываем в
3. Pipelines (конвейеры обработки)
Конвейеры — это цепочки обработки, где выход одного этапа — это вход следующего. Каждый шаг может быть реализован как горутина, соединённая каналами:
Такой стиль позволяет писать легко тестируемый, модульный и читаемый код.
https://www.dolthub.com/blog/2024-06-21-channel-three-ways/
👉 @golang_lib
Каналы в Go — мощный инструмент для взаимодействия между горутинами. Рассмотрим три идиоматичных способа их использования:
1. Fan-out (расщепление задач)
Fan-out — это когда несколько воркеров читают из одного канала задач. Это позволяет обрабатывать задачи параллельно:
ch := make(chan int)
for i := 0; i < 3; i++ {
go func() {
for task := range ch {
doWork(task)
}
}()
}
Задачи отправляются в
ch
, и любая из горутин может их подобрать и обработать.2. Fan-in (агрегация результатов)
Fan-in — это сбор результатов от нескольких источников в один канал. Используется, когда у нас несколько генераторов данных:
ch1 := make(chan int)
ch2 := make(chan int)
out := make(chan int)
go func() {
for {
select {
case v := <-ch1:
out <- v
case v := <-ch2:
out <- v
}
}
}()
Мы слушаем оба канала и всё складываем в
out
, где далее можно агрегировать или обрабатывать данные.3. Pipelines (конвейеры обработки)
Конвейеры — это цепочки обработки, где выход одного этапа — это вход следующего. Каждый шаг может быть реализован как горутина, соединённая каналами:
func gen() <-chan int {
out := make(chan int)
go func() {
for i := 0; i < 10; i++ {
out <- i
}
close(out)
}()
return out
}
func square(in <-chan int) <-chan int {
out := make(chan int)
go func() {
for v := range in {
out <- v * v
}
close(out)
}()
return out
}
for v := range square(gen()) {
fmt.Println(v)
}
Такой стиль позволяет писать легко тестируемый, модульный и читаемый код.
https://www.dolthub.com/blog/2024-06-21-channel-three-ways/
👉 @golang_lib
💡 Структура CLI-приложения на Go
Когда мы пишем CLI на Go, важно грамотно организовать структуру проекта. Вот распространённый и удобный шаблон:
📌 Основные моменты:
-
- Папка
- В
📁 Пример содержимого
А в
📦 Такой подход делает CLI-приложение масштабируемым и удобным для поддержки. Особенно если вы планируете добавлять новые команды или делегировать разработку другим.
https://www.bytesizego.com/blog/structure-go-cli-app
👉 @golang_lib
Когда мы пишем CLI на Go, важно грамотно организовать структуру проекта. Вот распространённый и удобный шаблон:
my-cli/
├── cmd/
│ ├── root.go
│ └── greet.go
├── internal/
│ └── greet/
│ └── greet.go
├── main.go
├── go.mod
📌 Основные моменты:
-
main.go
— точка входа. Здесь мы вызываем cmd.Execute()
.- Папка
cmd/
содержит все команды CLI. Например, greet.go
реализует команду greet
, а root.go
— основную/root-команду.- В
internal/greet/greet.go
размещаем бизнес-логику, отделяя её от логики CLI. Это улучшает читаемость, покрытие тестами и повторное использование кода.📁 Пример содержимого
cmd/greet.go
:
var greetCmd = &cobra.Command{
Use: "greet",
Short: "Выводит приветствие",
Run: func(cmd *cobra.Command, args []string) {
greet.SayHello()
},
}
А в
internal/greet/greet.go
:
func SayHello() {
fmt.Println("Привет от Go CLI!")
}
📦 Такой подход делает CLI-приложение масштабируемым и удобным для поддержки. Особенно если вы планируете добавлять новые команды или делегировать разработку другим.
https://www.bytesizego.com/blog/structure-go-cli-app
👉 @golang_lib
Обращаемся ко всем, кто пишет на Go и не только… Какие планы на 23 апреля?
Тогда решено — идём на Avito Go Drinkup #2 в офис на Лесной. Обещают «круглые столы», за которыми участники будут обсуждать:
➡️ Архитектуру микросервисов на Go;
➡️ Как перейти с другого языка на Go;
➡️ Карьерный путь в бэкенде;
➡️ Реальные кейсы использования Go.
И ещё много чего! Посмотреть подробнее и зарегистрироваться можно тут.
Тогда решено — идём на Avito Go Drinkup #2 в офис на Лесной. Обещают «круглые столы», за которыми участники будут обсуждать:
И ещё много чего! Посмотреть подробнее и зарегистрироваться можно тут.
Please open Telegram to view this post
VIEW IN TELEGRAM
Примеры использования
- Получение списка Pod'ов
- Прослушивание событий (watch)
- Использование контроллеров
- Работа с workqueue
- Создание кастомных клиентов
- Реализация информеров
- Примеры c RBAC и настройкой доступа
Каждый пример максимально изолирован и понятен, что делает репозиторий отличной стартовой точкой для тех, кто хочет разобраться, как изнутри работает Kubernetes-клиент на Go. Особенно полезно для разработчиков операторов и контроллеров.
https://github.com/iximiuz/client-go-examples
👉 @golang_lib
client-go
— официальной Go-библиотеки для взаимодействия с Kubernetes API. Репозиторий содержит набор минималистичных, но рабочих программ, которые демонстрируют, как использовать client-go
для различных задач:- Получение списка Pod'ов
- Прослушивание событий (watch)
- Использование контроллеров
- Работа с workqueue
- Создание кастомных клиентов
- Реализация информеров
- Примеры c RBAC и настройкой доступа
Каждый пример максимально изолирован и понятен, что делает репозиторий отличной стартовой точкой для тех, кто хочет разобраться, как изнутри работает Kubernetes-клиент на Go. Особенно полезно для разработчиков операторов и контроллеров.
https://github.com/iximiuz/client-go-examples
👉 @golang_lib
Выжимаем из Go максимум производительности
Разработчики, которые используют Go, сталкиваются с задачей выжать максимальную производительность из каждой строки кода. Но что делать, если оптимизировать уже нечего, а увеличивать скорость всё равно надо?
Меня зовут Никита Галушко. Я старший программист-разработчик в отделе высоконагруженных систем и оптимизации ВКонтакте. В статье поделюсь, какие хитрости помогут использовать Go на полную мощность.
О чём будет речь в статье
🔹Расскажу про память, а именно про small-size объекты и интерфейс, покажу пару трюков со стеком.
🔹Поделюсь, как сильно может влиять на производительность BCE (Bounds Check Elimination) и почему не все циклы for-loop одинаково полезны.
🔹Раскрою особенности, которые текущий компилятор Go накладывает на наш код.
🔹Затрону такие темы, как оптимальная конвертация
https://habr.com/ru/companies/vk/articles/824484/
👉 @golang_lib
Разработчики, которые используют Go, сталкиваются с задачей выжать максимальную производительность из каждой строки кода. Но что делать, если оптимизировать уже нечего, а увеличивать скорость всё равно надо?
Меня зовут Никита Галушко. Я старший программист-разработчик в отделе высоконагруженных систем и оптимизации ВКонтакте. В статье поделюсь, какие хитрости помогут использовать Go на полную мощность.
О чём будет речь в статье
🔹Расскажу про память, а именно про small-size объекты и интерфейс, покажу пару трюков со стеком.
🔹Поделюсь, как сильно может влиять на производительность BCE (Bounds Check Elimination) и почему не все циклы for-loop одинаково полезны.
🔹Раскрою особенности, которые текущий компилятор Go накладывает на наш код.
🔹Затрону такие темы, как оптимальная конвертация
string -> []byte
и []byte -> string
, конкатенация и связанные с ней оптимизация, сортировка []string
— это важно, так как в наших повседневных программах часто используются строки, и с типом string связано много мифов.https://habr.com/ru/companies/vk/articles/824484/
👉 @golang_lib
🚀 Как улучшить навыки разработки на Go?
Научитесь правильно использовать интерфейсы — ключ к гибкости и масштабируемости.
🗓 Присоединяйтесь к открытому вебинару 28 апреля в 20:00 мск и разберитесь, как эффективно применять интерфейсы в Go. На примерах мы разберем типовые ситуации и научим вас правильно интегрировать интерфейсы в код.
Понимание интерфейсов — ключ к эффективному проектированию приложений и обеспечению гибкости в коде.
➡️ Регистрируйтесь и получите скидку на курс «Golang Developer. Professional»: https://vk.cc/cL18Vb
Научитесь правильно использовать интерфейсы — ключ к гибкости и масштабируемости.
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Please open Telegram to view this post
VIEW IN TELEGRAM
🧠 Почему
Посмотрим:
Что здесь не так?
Если
💡 Как избежать
1. Всегда вызывай
2. Если передаёшь контекст в goroutine — убедись, что она завершится, даже если вызывающая функция ушла.
👉 @golang_lib
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