Telegram Web Link
🛠️ История создания “storage-agnostic” message queue

Автор — Fahim Faisaal — делится опытом разработки гибкой очереди задач на Go, которая может использовать любые хранилища: in-memory, Redis, SQLite и др. :contentReference[oaicite:0]{index=0}

Контекст:
Занимаясь на Go, автор вдохновился инструментами из Node.js экосистемы (BullMQ, RabbitMQ) и захотел сделать что-то похожее, но с нуля, без зависимостей. Так родилась идея — сначала он создал Gocq (Go Concurrent Queue): простую concurrent-очередь, работающую через каналы :contentReference[oaicite:1]{index=1}.

Основная проблема

Gocq отлично работал в памяти, но не поддерживал устойчивое хранение задач.
Автор задумался: а можно ли сделать очередь, не зависящую от конкретного хранилища — так, чтобы её можно было подключить к Redis, SQLite или совсем без них?
🧱 Как это реализовано в VarMQ

После рефакторинга Gocq был разделён на два компонента:
1. Worker pool — пул воркеров, обрабатывающих задачи.
2. Queue interface — абстракция над очередью, не зависящая от реализации.

Теперь воркер просто берёт задачи из очереди, не зная, где они живут. :contentReference[oaicite:2]{index=2}

---

### 🧠 Пример использования

- In-memory очередь:

w := varmq.NewVoidWorker(func(data any) {
// обработка задачи
}, 2)
q := w.BindQueue()


- С SQLite-поддержкой:

import "github.com/goptics/sqliteq"

db := sqliteq.New("test.db")
pq, _ := db.NewQueue("orders")
q := w.WithPersistentQueue(pq)


- С Redis (для распределённой обработки):

import "github.com/goptics/redisq"

rdb := redisq.New("redis://localhost:6379")
pq := rdb.NewDistributedQueue("transactions")
q := w.WithDistributedQueue(pq)


В итоге воркер обрабатывает задачи одинаково — независимо от хранилища. :contentReference[oaicite:3]{index=3}

Почему это круто


- Гибкость: адаптеры позволяют легко менять хранилище без правок воркера.
- Минимальные зависимости: в ядре — zero-deps, весь функционал — через адаптеры.
- Self-hosted и легковесно: можно развернуть локально или в продакшене.
- Написано на Go: использует горутины и каналы, удобен и эффективен.

📣 Отзывы сообщества

На Reddit отметили, что автор добился "queue system that doesn’t care if your storage is Redis, SQLite, or even in-memory" :contentReference[oaicite:4]{index=4}

🔗 Ссылки
- Статья: A Story of Building a Storage‑Agnostic Message Queue на DEV :contentReference[oaicite:5]{index=5}
- GitHub VarMQ (Var-storage-agnostic message queue): репозиторий с кодом адаптеров и примерами использования :contentReference[oaicite:6]{index=6}

Итог: VarMQ — это элегантное решение на Go для создания задач-очереди, универсально по отношению к хранилищу: выбрал нужный адаптер — и система работает.

📌 Читать
🧪 Go synctest — решение для нестабильных (flaky) тестов

Flaky-тесты в многопоточном Go-коде — боль. Новый экспериментальный инструмент synctest из Go 1.24 решает эту проблему с помощью синтетического времени и контроля исполнения goroutine.

📌 Что это такое:
synctest — специальный режим, запускающий тесты в изолированной "песочнице", где:
time.Sleep не ждёт реального времени
• все goroutine исполняются детерминированно
• нет зависимости от планировщика и нагрузки ОС

🔧 Пример:


import "testing/synctest"

func TestSharedValue(t *testing.T) {
synctest.Run(func() {
var shared atomic.Int64
go func() {
shared.Store(1)
time.Sleep(1 * time.Microsecond)
shared.Store(2)
}()
time.Sleep(5 * time.Microsecond)
if shared.Load() != 2 {
t.Errorf("shared = %d, want 2", shared.Load())
}
})
}


Даже с Sleep, результат всегда стабилен. Без synctest такой тест может иногда проваливаться.

⚙️ Преимущества:
Устранение race-условий при тестировании
Нет задержек — Sleep срабатывает мгновенно
Можно тестировать поведение с точностью до микросекунды
Подходит для любых atomic, mutex, select, time.After и др.

🚫 Ограничения:
• Пока экспериментально: нужно запускать с GOEXPERIMENT=synctest
• Не подходит для ввода-вывода, работы с сетью или временем вне "bubble"

📖 Подробнее:
https://victoriametrics.com/blog/go-synctest/
Расширенный_гайд_по_Docker_для_DevOps_специалистов_1_2.pdf
391.1 KB
🐳 Docker без боли: Огромный гайд от новичка до профи

🚀 Пришло время расставить всё по полочкам. В этом большом гайде ты узнаешь:

• как устроен Docker изнутри
• как упаковать любое приложение в контейнер
• как запускать десятки сервисов одной командой
• как дебажить, оптимизировать и защищать контейнеры
• как не сойти с ума с volumes, networks и образами

🎯 Без скучной теории — только практические команды, схемы и лайфхаки от тех, кто использует Docker в продакшене.
Сохраняй и делись с коллегами, чтобы не потерять

👉 Читать онлайн

@golang_books
Please open Telegram to view this post
VIEW IN TELEGRAM
📢 GORM теперь поддерживает дженерики — работа с БД в Go стала ещё проще и безопаснее!

С версии GORM v1.30.0 появилась полноценная поддержка дженериков (Go 1.18+), которая позволяет писать более выразительный и типобезопасный код без шаблонных повторов.

🔧 Пример:


ctx := context.Background()

// Создание
gorm.G[User](db).Create(ctx, &User{Name: "Alice"})

// Поиск
user, err := gorm.G[User](db).Where("name = ?", "Alice").First(ctx)

// Обновление
gorm.G[User](db).Where("id = ?", user.ID).Update(ctx, "age", 30)

// Удаление
gorm.G[User](db).Where("id = ?", user.ID).Delete(ctx)


Что это даёт:
• Типобезопасность на этапе компиляции
• Более компактный и читаемый код
• Лёгкая интеграция с OnConflict, Joins, Hints, Preload и пр.
• Улучшенный DX (developer experience)

📎 Документация: https://gorm.io/docs/the_generics_way.html

Если ты пишешь на Go и используешь GORM — самое время перейти на новый стиль.
🚀 Кэширование в Go: как делать правильно

В свежей статье от Leapcell рассматриваются ключевые аспекты эффективного кэширования в Go:

- Планирование объёма памяти: важно заранее оценить, сколько данных будет кэшироваться, чтобы избежать переполнения памяти (OOM).

- Классификация данных: разделение данных на "горячие" и "холодные" помогает оптимизировать использование ресурсов, сохраняя часто используемые данные в быстром доступе, а редко используемые — на более экономичных носителях.

- Стратегии кэширования в распределённых системах:
- Использование распределённого кэша (например, Redis).
- Направление одинаковых запросов на один и тот же экземпляр приложения.
- Репликация кэша на каждом экземпляре приложения.

- Политики вытеснения: применение алгоритма LRU (Least Recently Used) помогает контролировать размер кэша, удаляя наименее используемые элементы.

Подробнее: https://dev.to/leapcell/caching-in-go-doing-it-right-25i5
🚀 Go — идеально подходит для AI-агентов

Агент дорогим в использовании (например, из-за использования LLM), и часто требует взаимодействия с пользователем или другими агентами.

⚙️ Преимущества Go для работы с агентами:
- Go позволяет запускать тысячи горутин с минимальными накладными расходами, что идеально подходит для масштабируемых агентных систем.

- Общение через каналы: Go поощряет передачу данных через каналы, что упрощает синхронизацию и уменьшает вероятность ошибок, связанных с общим доступом к памяти.

- Контекстное управление: Механизм context.Context в Go обеспечивает централизованное управление отменой операций, что особенно полезно для долгоживущих процессов.

- Богатая стандартная библиотека: Go предоставляет обширный набор инструментов для работы с сетью, JSON, криптографией и другими аспектами, необходимыми для разработки агентов.

- Профилирование: Инструменты, такие как pprof, позволяют эффективно отслеживать и устранять утечки памяти и горутин.

🙅 Минусы:
— Мало библиотек для ML
— Нет "магии" как у Python-экосистемы

Но если тебе важны надежность, скорость и контроль, Go — это отличный выбор 🔥

📖 Читать полностью
🌀 Middleware и RoundTripper в Go: гибкая обработка HTTP-запросов

В Go нет встроенного понятия "middleware", как в других фреймворках — но вы можете легко реализовать его сами, особенно в контексте http.RoundTripper.

🔧 RoundTripper — это интерфейс, который обрабатывает HTTP-запросы на уровне клиента (`http.Client`). Это даёт возможность внедрять логику *до* и *после* отправки запроса.

🧱 Пример: логгер запросов

type LoggingRoundTripper struct {
rt http.RoundTripper
}

func (l *LoggingRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
log.Printf("📤 Запрос: %s %s", req.Method, req.URL)
resp, err := l.rt.RoundTrip(req)
if err == nil {
log.Printf("📥 Ответ: %d", resp.StatusCode)
}
return resp, err
}


📦 Использование:

client := &http.Client{
Transport: &LoggingRoundTripper{rt: http.DefaultTransport},
}


💡 Таким образом, вы можете создавать middleware прямо внутри http.Client, например:
• логирование
• кэширование
• модификация заголовков
• retry-логика
• трейсинг

🔗 Подробнее: dev.to/calvinmclean/middleware-and-roundtrippers-in-go-30pa

#golang #httpclient #middleware #webdev #devtools
👣 Как работает разметка диска: парсим MBR и GPT на Go

Отличный технический гайд — как на языке Go реализовать свой инструмент для анализа разделов диска (аналог `fdisk -l`), работая напрямую с «сырыми» байтами.

📌 Что делает утилита:
• Считывает первые 512 байт с диска (MBR)
• Определяет тип таблицы разделов: MBR или GPT
• Парсит нужные структуры (MBRPartition, GPTHeader и др.)
• Выводит информацию о каждом разделе: смещение, размер, активность, тип, имя (для GPT)

🔧 Поддерживается два формата:
1. MBR (Master Boot Record)
• До 4 основных разделов
• Ограничение — 2 ТБ
• Таблица находится в первом секторе (512 байт)
• Каждая запись — 16 байт, с полями CHS, LBA, типом и флагами
• В конце сигнатура 0x55AA

2. GPT (GUID Partition Table)
• Современный стандарт с поддержкой >2 ТБ
• Использует специальные GUID-идентификаторы
• Поддерживает до 128 разделов
• Содержит основной и резервный заголовки + таблицу с метаданными и именами разделов в UTF‑16

📖 Примеры кода в Go:
• Структуры описаны через struct с бинарными полями
• Используется binary.Read для чтения блоков
• Есть вспомогательные функции для расшифровки типов и конвертации размеров

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

💡 Почему это полезно:
• Позволяет лучше понять, как устроена разметка дисков
• Учит читать бинарные форматы и парсить их в Go
• Подходит для системного программирования, утилит, диагностики и низкоуровневой работы с железом

🧪 Автор также упоминает возможные улучшения:
• Проверка CRC
• Поддержка расширенных и логических разделов
• Чтение заголовков файловых систем
• Реализация в WebAssembly для запуска в браузере

📎 Читать
Please open Telegram to view this post
VIEW IN TELEGRAM
👣 Rust vs Go: Что выбрать в 2025 году

Пейзаж программирования продолжает развиваться: языки Rust и Go бросают вызов традиционным парадигмам и удовлетворяют высокие требования современности. Оба находят важные ниши благодаря эффективной работе на уровне системы и возможностям в конкуренции blog.jetbrains.com.

Согласно данным отчёта State of Developer Ecosystem за 2024 год, Rust установил рекорд популярности — 2,27 млн. пользователей, из которых 709 000 используют его как основной язык. Пользователей Go стабильно много, и каждый шестой сейчас задумывается о переходе на Rust blog.jetbrains.com.

Выбор между ними зависит от требований проекта — будь то производительность, удобство или конкуренция. Давайте разберём оба языка.

📌 Читать
Please open Telegram to view this post
VIEW IN TELEGRAM
⚙️ Написание собственного Load Balancer всего за 250 строк кода

В свежей статье на *Beyond the Syntax* Sushant Dhiman показывает, как создать HTTP‑балансировщик нагрузки с нуля, используя всего ~250 строк Go-кода!

👨‍💻 Что в статье:
- Простой балансировщик, который принимает HTTP-запросы и распределяет их на пул серверов.
- Поддержка алгоритма round‑robin.
- Health‑checks: временно убирает из пула серверы, которые не отвечают.
- Как добавлять и убирать бэкенды динамически.
- Версия с конкурентной обработкой запросов.

🧩 Почему это полезно:
- Понятный, минималистичный код — отлично подойдёт для учебы и практики.
- Пошагово объясняется каждый компонент: от приёма соединений до проверок здоровья серверов.
- Реализация буквально «на коленке», без сложных фреймворков.

🚀 Итог:
Учебный, но практичный пример, как за минимальными усилиями и строками кода получить работующий Layer‑7 балансировщик. Отлично для новичков и тех, кто хочет вникнуть «под капот» инфраструктуры.

🔗 Читайте статью

@golang_books
♟️ Новая шахматная библиотека на Go — chess v2

Разработчик Brigham Skarda представил chess v2 — лёгкую и мощную библиотеку для работы с шахматами на языке Go.

📦 Что умеет:
• Валидация и исполнение ходов
• Поддержка PGN и FEN
• Расчёт состояния: шах, мат, пат, троекратное повторение
• Работа с произвольных позиций

🔧 Отличия версии v2:
• Переработанный API с акцентом на читаемость и безопасность
• Повышенная производительность
• Улучшенная архитектура — удобна для использования в ИИ, анализаторах партий и игровых движках

🚀 Отличный инструмент для тех, кто пишет:
• шахматные движки
• телеграм-ботов
• шахматные редакторы и визуализаторы

🔗 Статья: https://brighamskarda.com/articles/introducing_chess_v2_a_new_chess_library_in_golang

#golang #chess #opensource #gamedev #библиотекиGo
📝 Trumbowyg: лёгкий WYSIWYG-редактор для веб-разработчиков

🚀 Основные преимущества
• Мини-размер: ~30 KB JS (10 KB gzip) — мгновенная загрузка
• Простая инициализация:

$('#editor').trumbowyg();

• Семантический HTML без «вредных» обёрток
• Богатый набор кнопок: жирный, курсив, списки, ссылки, вставка изображений и многое другое
• Кроссбраузерность: IE9+ и все современные браузеры

🎯 Установка и подключение
• Подключи jQuery и стили/скрипты Trumbowyg

<link rel="stylesheet" href="dist/ui/trumbowyg.min.css">
<script src="dist/trumbowyg.min.js"></script>

• Инициализируй редактор с параметрами:

$('#editor').trumbowyg({
btns: [
['strong','em'],
['link','insertImage'],
['unorderedList','orderedList']
],
autogrow: true
});


🛠 Плагины и расширяемость
• Более 35 официальных плагинов: таблицы, эмодзи, автосохранение, автоподгонка высоты, fullscreen и др.
• Подключи плагин — инициализируй сразу после основного скрипта:

$.trumbowyg.plugins.autosave = {
fn: {
init: function(t) { /* … */ }
}
};
$('#editor').trumbowyg({ plugins: { autosave: { delay: 5000 } } });


⚙️ Кастомизация
• Настраиваемые тулбары: создавай свои группы кнопок
• Локализации на более чем 45 языков
• Собственные модальные окна:

var $modal = $('#editor').trumbowyg('openModal', {
title: 'Моё окно',
content: '<p>Любой HTML</p>'
});
$modal.on('tbwconfirm', () => $('#editor').trumbowyg('closeModal'));


🌐 Когда выбирать Trumbowyg
• Если важна скорость загрузки и простота
• Для админок, CMS и лёгких веб-приложений
• Когда нужен чистый семантический код и минимальные зависимости

🔗 Полезные ссылки
• Документация и демо: https://alex-d.github.io/Trumbowyg/
• Репозиторий GitHub: https://github.com/Alex-D/Trumbowyg
📁 Go: быстрая обработка гигантских файлов

Подход к обработке огромных файлов (миллионы строк) в Go: быстро, параллельно и без лишнего потребления памяти.

🔧 Идея: pipeline с каналами и воркерами

1. Читаем файл по строкам через bufio.Scanner
2. Передаём строки в батчах (например, по 100 000) в канал
3. Несколько горутин-воркеров обрабатывают эти батчи
4. Объединяем результаты и записываем/анализируем дальше

💡 Результаты:
• Последовательная обработка занимала ~19 секунд
• Параллельная (10 воркеров + batch size 100 000) — ~9 секунд
• Потребление памяти остаётся стабильным, даже на файлах 20+ ГБ

🛠 Почему это эффективно:
• Каналы позволяют читать и обрабатывать одновременно
• Батчи уменьшают количество аллокаций
• Возможна повторная инициализация []string через sync.Pool
• GC остаётся под контролем — без резких пиков

Подходит для:
• CSV, JSONL, логов, текстовых потоков
• ETL-пайплайнов: чтение → обработка → сохранение
• Стриминговой обработки в аналитике и ML

📌 Советы:
• Используй runtime.NumCPU() для адаптивного количества воркеров
• Подбирай batchSize экспериментально (10–100 тыс строк)


Читать
Тимлид, вам слово📣 Приглашаем на митап по управлению командами

Воспользуйтесь летним затишьем, чтобы посмотреть на практику коллег, промониторить «погоду» в своей команде и, возможно, обновить стратегию работы. Обсудим дела тимлидские на офлайн-встрече TeamLead Talks в офисе Lamoda.  

🤝 Обменяемся опытом, разберем кейсы командного управления и выберем лучшие решения.

🍕 Наладить непринужденное общение помогут нетворкинг-разогрев, игра «IT-бункер», закуски и напитки.

Присоединяйтесь к Team Lead Talks:
📅 2 июля в 19:00.
📍 Офлайн, Москва, офис Lamoda.  
🔗Регистрируйтесь по ссылке, количество мест ограничено.

#реклама
О рекламодателе
🔐 Непредвиденные уязвимости в парсерах Go

Go-разработчики нередко упускают из виду, как стандартные JSON / XML / YAML-парсеры могут быть использованы злоумышленниками, что приводит к обходу аутентификации и утечке данных.

1. Опасные теги при (un)marshal

* Поля без json:"-" участвуют в Unmarshal.
* Неверные теги:
* json:"-,omitempty" — парсер ждёт ключ "-", поле остаётся доступным.
* json:"omitempty" — имя поля становится "omitempty", модификатор не работает.

Решение: использовать json:"-" и Semgrep-правила:
trailofbits.go.unmarshal-tag-is-dash и trailofbits.go.unmarshal-tag-is-omitempty.

2. Несогласованность парсеров

* Дубликаты ключей: Go берёт последнее значение, другие парсеры — первое или ошибку.
* Регистронезависимый поиск: {"ACTION":"X"} читается как Action только в Go.
* Unicode-подмена имён (`aKtionſ`) проходит незамеченной.

3. Путаница форматов

* XML-парсер Go игнорирует мусор до/после документа → JSON-внедрение.
* YAML-парсер принимает JSON как валидный YAML.
* Пример CVE-2020-16250 (Hashicorp Vault): JSON в XML-парсер → обход auth.

Рекомендации

* Жёсткий режим:
* JSON — decoder.DisallowUnknownFields()
* YAML — KnownFields(true)
* Свой строгий парсер с проверкой дубликатов и case-collisions.
* Единый парсер и настройки во всех сервисах.
* Следить за безопасными дефолтами JSON v2 в Go.
* Использовать Semgrep для поиска рисков.

Ключевые выводы

1. Включить строгий парсинг.
2. Синхронизировать настройки во всех микросервисах.
3. Переходить на JSON v2, когда он стабилизируется.
4. Периодически запускать статический анализ (Semgrep).

Go-парсеры удобны, но при работе с недоверенными данными необходимы дополнительные меры.

📌 Читать
2025/07/05 14:12:22
Back to Top
HTML Embed Code: