Golang Portal
8K subscribers
413 photos
26 videos
7 files
444 links
Присоединяйтесь к нашему каналу и погрузитесь в мир для Golang-разработчика

Связь: @devmangx
Download Telegram
Каналы в Go — это интересная и поначалу достаточно сложная для понимания концепция.

Если вы пришли из традиционных языков, таких как Java, то вы, скорее всего, использовали потоки с мьютексами или асинхронные очереди вроде Apache Kafka для организации взаимодействия между разными частями программы.

Синтаксис каналов может показаться странным, а семантика — расплывчатой, но они становятся понятнее, если воспринимать их как конкурентные очереди.

Канал в Go — это просто очередь, через которую можно передавать данные.

Если вы записываете в канал — это эквивалентно добавлению элемента в очередь.
Если вы читаете из канала — вы извлекаете первый элемент из очереди.
Очередь работает по принципу FIFO (первым пришёл — первым вышел).

У каналов множество применений. Например, представьте, что у вас есть HTTP-обработчик, и после завершения его работы вы хотите запустить дополнительную вычислительную задачу. Вы могли бы использовать асинхронную очередь для запуска workflow, а можете — канал.

В коде вы просто записываете значение в канал, например struct{user userID; data interface{}}, и это может послужить триггером для запуска другой вычислительной задачи.

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

Вы можете контролировать, сколько сигналов канал может буферизовать, указывая размер буфера при создании через make (например, userChan := make(chan interface{}, capacity)).

Можно создать канал, принимающий единичный сигнал (например, сигнал для закрытия базы данных), или буферизированный канал, в который несколько горутин записывают результаты своей работы.

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

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

По сути, каналы — это отличный способ организации взаимодействия между последовательными процессами, что и составляет суть модели конкурентности CSP (Communicating Sequential Processes) в Go.

Вот пример кода, показывающий мощь каналов. В Go существует возможность подписаться на сигналы операционной системы через канал.

Например, если программа завершается, вызывает панику, прерывается или останавливается — мы можем получить сообщение об этом через канал и корректно завершить работу сервера (записать состояние в лог, закрыть подключения к БД, завершить файловые операции и т. д.).

👉 @juniorGolang | #tip
Please open Telegram to view this post
VIEW IN TELEGRAM
6👍4
⚙️ Утилита для парсинга лог-файлов в форматах Common и Combined Log Format (CLF) и сохранения их в SQLite для последующего анализа. Разработана с учетом конкурентности.

https://github.com/thevxn/xilt

👉 @juniorGolang | #ресурсы
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍2
This media is not supported in your browser
VIEW IN TELEGRAM
Большая актуальная базу бесплатных API, которая обновляется ежедневно

Тут собрано аж 363 бесплатных API на все случаи жизни: от игр и погоды до финансов и здоровья.

Алгоритмы присваивают рейтинг каждому API на основе надежности, частоты ошибок и времени отклика

Если API перестает работать или становится платным, он теряет рейтинг и удаляется с сайта

Переходите и смотрите сами: https://www.freepublicapis.com/

👉 @juniorGolang | #ресурсы
Please open Telegram to view this post
VIEW IN TELEGRAM
👍83
Самостоятельно размещаемая альтернатива Google Analytics, реализованная на Go

https://github.com/vinceanalytics/vince

👉 @juniorGolang | #ресурсы
Please open Telegram to view this post
VIEW IN TELEGRAM
👍61
Принёс шпаргалку с 12 командами Git, которые «должен знать каждый разраб»

1. git init – инициализация нового Git-репозитория в текущем каталоге.

2. git add – добавление изменений в индекс (staging area).

3. git commit – фиксация проиндексированных изменений с комментарием.

4. git push – отправка локальных изменений в удалённый репозиторий.

5. git pull – получение изменений из удалённого репозитория и их слияние с локальной веткой.

6. git remote – добавление, просмотр или удаление удалённого репозитория.

7. git branch – вывод списка веток, создание новой ветки и переключение на неё.

8. git fetch – загрузка изменений из удалённого репозитория без их слияния.

9. git checkout – переключение на указанную ветку.

10. git merge – слияние указанной ветки с текущей.

11. git status – отображение текущего состояния репозитория и неподтверждённых изменений.

12. git reset – откат текущей ветки до указанного коммита.


Сохраняем и пользуемся

К слову, Git на днях отметил своё 20-летие — 7 апреля 2005 года Линус Торвальдс написал его всего за пару недель, чтобы заменить BitKeeper при разработке ядра Linux

С тех пор без Git не обходится почти ни один проект ✌️

👉 @juniorGolang
Please open Telegram to view this post
VIEW IN TELEGRAM
8👍5
Пакет Go, который декодирует url.Values в значения Go и кодирует значения Go в url.Values. Поддержка как массивов, так и полных отображений

https://github.com/go-playground/form

👉 @juniorGolang | #ресурсы
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
gRPC в Go: Потоковые RPC, перехватчики и метаданные

Это самое полное базовое руководство, охватывающее типы RPC, перехватчики, заголовки, трейлеры и многое другое

https://victoriametrics.com/blog/go-grpc-basic-streaming-interceptor/

👉 @juniorGolang | #cтатья
Please open Telegram to view this post
VIEW IN TELEGRAM
👍62🔥2
⚙️ Порт свежего агента от OpenAI Codex CLI на Go — легковесный мультимодальный агент для написания кода на естественном языке, работающий прямо в терминале.

https://github.com/epuerta9/codex-go

👉 @juniorGolang | #ресурсы
Please open Telegram to view this post
VIEW IN TELEGRAM
4
Если вы хотите протестировать производительность своего Go-кода, вы можете написать несколько бенчмарк-тестов.

Они анализируют скорость выполнения и использование памяти различными функциями и блоками кода.

Здесь Педро показывает, как писать бенчмарк-тесты для ваших функций на Golang:

https://freecodecamp.org/news/how-to-write-benchmark-tests-for-your-golang-functions/

👉 @juniorGolang | #cтатья
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍2
Начиная с Go 1.8, стандартная библиотека http.Server включает метод Shutdown, который критически важен для корректного завершения работы веб-сервисов.

Этот метод обеспечивает "плавное" завершение работы сервера, поскольку он:

🔹Немедленно прекращает приём новых подключений

🔹Сохраняет существующие подключения активными до завершения всех текущих запросов

🔹Предоставляет контекст для управления таймаутом на завершение "висящих" запросов

🔹Завершается только после обработки всех находящихся в процессе выполнения запросов

🔹Предотвращает утечки подключений при завершении работы приложения

Без корректного завершения, принудительное завершение работы сервера может привести к обрыву активных запросов, ошибкам на стороне клиента и потенциальной неконсистентности данных.

Метод Shutdown элегантно решает эту проблему. Ниже приведена полноценная реализация, демонстрирующая обработку нескольких сигналов ОС для плавного завершения работы:

👉 @juniorGolang | #tip
Please open Telegram to view this post
VIEW IN TELEGRAM
14👍9
This media is not supported in your browser
VIEW IN TELEGRAM
Лёгкая очередь сообщений, реализованная на Go, с поддержкой SQLite, PostgreSQL и ORM в качестве постоянного хранилища

https://github.com/ixugo/nsqite/blob/master/README.md

👉 @juniorGolang | #ресурсы
Please open Telegram to view this post
VIEW IN TELEGRAM
👍81
При разработке приложений, использующих LLM API, таких как OpenAI или Anthropic, вы быстро упрётесь в лимиты запросов при масштабной обработке. Пакет rate из https://golang.org — хорошее решение этой проблемы, так как он:

🔹Реализует лимитирование скорости на основе алгоритма token bucket с точной настройкой

🔹Поддерживает ожидание с учётом контекста и возможностью отмены

🔹Эффективно обрабатывает всплески нагрузки благодаря настраиваемому размеру «ведра»

🔹Органично интегрируется с моделью конкурентности Go

Алгоритм token bucket особенно хорошо подходит для LLM‑API. Каждый запрос потребляет один токен из «бакета», который пополняется с заданной скоростью. Если «бакет» пуст, запросы ожидают появления токенов вместо того, чтобы сразу завершаться с ошибкой.

Выше приведён пример кода с неофициальным клиентом OpenAI и использованием пакета rate

👉 @juniorGolang | #tip
Please open Telegram to view this post
VIEW IN TELEGRAM
👍71
⚙️ Лёгкая, типобезопасная система публикации/подписки для Go, использующая дженерики и отмену на основе контекста

https://github.com/sesopenko/genericpubsub

👉 @juniorGolang | #ресурсы
Please open Telegram to view this post
VIEW IN TELEGRAM
3
Если вы обрабатываете HTTP-запросы на Go, сжатие gzip является важным инструментом для снижения потребления трафика и ускорения отклика. Пакет encoding/gzip упрощает реализацию, но есть некоторые подводные камни, о которых стоит помнить.

При реализации gzip-сжатия в веб-серверах:

🔹Всегда проверяйте заголовок Accept-Encoding перед применением сжатия

🔹Устанавливайте корректный заголовок ответа Content-Encoding

🔹Избегайте сжатия уже сжатых форматов (например, изображений, видео)

🔹Используйте sync.Pool для повторного использования gzip-писателей и повышения производительности

Вот пример реализации с использованием паттерна middleware.

👉 @juniorGolang | #tip
Please open Telegram to view this post
VIEW IN TELEGRAM
👍142
⚙️ P2P (peer-to-peer) шахматная игра с текстовым интерфейсом пользователя (TUI) на Go.

https://github.com/boozec/rahanna

👉 @juniorGolang
Please open Telegram to view this post
VIEW IN TELEGRAM
👍101
Дженерики в Go: Ваш дружелюбный гид по повторно используемому коду

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

👉 Читать

👉 @juniorGolang | #cтатья
Please open Telegram to view this post
VIEW IN TELEGRAM
7👍5
⚙️ Линтер для Go, который обеспечивает единообразие стиля кода при использовании log/slog

https://github.com/go-simpler/sloglint

👉 @juniorGolang
Please open Telegram to view this post
VIEW IN TELEGRAM
9
Сигнал SIGHUP для перезагрузки конфигурации

SIGHUP — это сигнал, находящийся на стыке двух миров. Он возник из-за физического «обрыва» соединения с терминалом, и его изначальное значение — потеря управляющего терминала — актуально до сих пор.

Многие приложения, включая приложения на Go (по умолчанию), обрабатывают три сигнала для завершения работы: SIGTERM, SIGINT и SIGHUP. Среди них SIGHUP несет дополнительные нюансы и сегодня может иметь меньшее значение.

По определению:
SIGHUP («signal hang up») — это сигнал, отправляемый процессу при закрытии его управляющего терминала. — Википедия


Но что именно представляет собой «управляющий терминал»?

👉 Читать далее

👉 @juniorGolang | #cтатья
Please open Telegram to view this post
VIEW IN TELEGRAM
👍64
С помощью Go можно создавать и запускать последовательные программы, которые обмениваются данными друг с другом через каналы.

Однако поведение каналов по умолчанию — блокирующее, если нет данных для чтения:
<-channel (будет ожидать, пока не появятся данные)

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

Если выполнение блокируется на первом канале, как оно узнает о сообщении во втором? Решением является мультиплексирование каналов, и в Go это делается с помощью ключевого слова select.

Ключевое слово select в Go синтаксически похоже на оператор switch, но используется для мультиплексирования каналов, то есть для одновременного прослушивания нескольких каналов. Каждый case — это операция с каналом, при выполнении которой исполняется соответствующий блок кода (чтение из канала или запись в него).

Вы можете явно блокировать выполнение или использовать default-ветку, чтобы продолжить выполнение без блокировки.

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

В приведённом примере мы мультиплексируем каналы, чтобы добиться всего этого:

В первом case мы получаем данные из очереди для дальнейшей обработки. Если канал закрыт — выходим из воркера.

Внутри этого блока создаётся context с тайм-аутом 30 секунд, который передаётся в функцию, обрабатывающую задачу с учётом тайм-аута. Это критически важно — так ни одна задача не сможет бесконечно блокировать воркер.

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

После завершения обработки (успешной или по тайм-ауту) вызывается cancel(), чтобы освободить ресурсы, связанные с контекстом. Даже если операция завершилась по тайм-ауту, явный вызов cancel() — это хорошая практика в Go для корректной очистки ресурсов.

Далее мы пытаемся отправить результат в канал результатов, но с дополнительной защитой — мы не хотим блокироваться, если получатель не успевает обрабатывать данные.

Снова используется select с default-веткой: если канал результатов переполнен, логируется предупреждение, и воркер сразу переходит к следующей задаче без ожидания. Такой неблокирующий подход предотвращает зависание воркера и позволяет ему продолжать работу даже при перегрузке получателя.

Второй case в основном select-блоке обрабатывает корректное завершение работы — при отмене родительского контекста воркер очищает ресурсы и завершает выполнение.

Третий case реализует периодическую проверку состояния (health check) каждые 5 минут бездействия. Это необходимо для выполнения обслуживающих задач, таких как очистка устаревших соединений, даже если нет новых задач.

Такой шаблон элегантно решает сразу несколько задач: обработку задач, учёт тайм-аутов, корректное завершение, доставку результатов и регулярное обслуживание — при этом предотвращая утечки ресурсов.

👉 @juniorGolang
Please open Telegram to view this post
VIEW IN TELEGRAM
👍96🔥3
Вышел Pion WebRTC v4.1.0 — стабильная поддержка полного AV1, передача больших сообщений через DataChannels и RTP-пейлоадер для H.265

https://github.com/pion/webrtc/releases/tag/v4.1.0

👉 @juniorGolang
Please open Telegram to view this post
VIEW IN TELEGRAM
👍92
Golang sync.Pool — не серебряная пуля

Когда речь заходит об оптимизации производительности в Go, sync.Pool часто выглядит как заманчивое решение. Он обещает сократить количество аллокаций памяти и снизить нагрузку на сборщик мусора за счёт повторного использования объектов. Но всегда ли это правильный выбор? Давайте углубимся в эту интересную тему.

👉 Читать

👉 @juniorGolang
Please open Telegram to view this post
VIEW IN TELEGRAM
👍72🌭1