ptah.runВ июне прошлого года я занимался разработкой проекта для собственных нужд (inventario), где заодно игрался с новыми фичами go, архитектурой кода и агентной разработкой. Благодаря этому проекту, кстати, я смог найти и зарепортить баг с имплементацией дженериков в go.Изначально простой проект разросся. Росло количество моделей и связей между ними. В какой-то момент я подумал, что неплохо бы озаботиться миграциями для моей системы. Я посмотрел, что имеется в наличии, и мне не зашло ничего.…
TLDR; https://github.com/alterfo/moex-traderЗдравствуйте, меня зовут Олег. 11+ лет опыта в архитектуре и управлении разработкой.Я как кузнец — не могу не куя, и сейчас, в меж-работье, занимаюсь своими проектами. Среди них — интерактивный нотный тренажер для игры на пианино, шифрованный личный дневник, игра по мотивам Космических Рейнджеров - Вакуумные Пройдохи и ещё штук 6, включая движок базы знаний по коду, чатам, докам и таскам и редактор IDEF0.Сейчас в фокусе проект AI-трейдинга.Мысль о зар…
Совсем недавно вышел Go 1.27. Я пошел изучать release notes и наткнулся там на следующее:Faster memory allocation The compiler now generates calls to size-specialized memory allocation routines, reducing the cost of some small (<80 byte) memory allocations by up to 30%. Improvements vary depending on the workload, but the overall improvement is expected to be ~1% in real allocation-heavy programs. This causes the binary size to increase by about 60 KB (independent of the workload). Please fi…
Всем привет! В данной статье расскажу про проект logporter, который для меня полностью заменил решение от Google для централизованного и полнофункционального мониторинга контейнеров Docker.Экспортер написан на Go и совмещает функции сборщика метрик, логов, проверки обновлений образов и встроенной панели мониторинга в одном легковесном образе.ПроизводительностьЭкспортер cAdvisor давно стал стандартом де-факто, когда требуется отслеживать производительность контейнеров на базе стека мониторинга P…
Три истории, у которых одно общее: всё собралось.Два пула. Соединения к базе понадобились в двух местах, и в каждом честно вызвали NewPool(). Компилируется, работает, тесты зелёные. Обнаруживается по графику числа коннектов через месяц, когда база начинает упираться в лимит.Не тот кэш. Есть два Cache — общий и локальный для тяжёлых выборок. В один сервис передали не тот. Типы совпадают, компилятор доволен, поведение правдоподобное: просто иногда данные свежее, чем должны быть, а иногда наоборот…
Привет, Хабр!На входе стоит валидатор: JSON Schema, которая знает про поле is_admin и снаружи выставлять его не даёт. Всё прочее схема считает лишним и пропускает не глядя. За валидатором Go‑сервис, там структура с тегом json:"is_admin". Приходит тело, где ключ написан заглавными — IS_ADMIN. Схема сравнивает строки побуквенно, такого имени не знает, пропускает. А json.Unmarshal знает и кладёт true куда надо.Никто из двоих при этом не ошибся: схема отработала по спецификации, encoding/js…
ВведениеПривет, Хабр! Эта статья посвящается важной теме работы в многопоточной среде. Для безопасной работы с одним ресурсом из разных горутин разработчик должен быть уверен в безопасности и обособленности действий, чтобы не создать ситуации, в которых "гонки данных" (data race) ломали бы важную логику и создавали коллизии данных.В случаях, когда нужно обращаться к одному источнику из разных горутин в Go обычно используют sync/atomic или Mutex. Основная задача текущей статьи рассказать…
Работа с гигантской памятью из Go на выделенном сервереМассив на 160 ГиБДля одной научно-исследовательской задачи мне понадобился массив на 160 ГиБ. Требования к нему простые: максимально быстрый случайный доступ к элементам, быстрый захват памяти при создании и быстрое освобождение при уничтожении. Последние два пункта важны, потому что содержимое массива подбирается итерациями, и на каждой он создаётся заново.Выходом стал выделенный сервер и Huge Pages размером 1 ГиБ. Но прежде чем их использ…
С сериализацией всё вроде бы просто. Есть значение x, мы превращаем его в последовательность байт, передаём куда‑то ещё, а потом восстанавливаем:x → encode → bytes → decode → x'И первое, что хочется проверить:decode(encode(x)) == xЕсли получилось — значит, сериализация работает. По крайней мере, так кажется. Потому что в этой формуле есть одна маленькая деталь, которую легко не заметить: что именно означает ==?Когда одинаковое — не то же самоеВозьмём совершенно обычный Go‑код: a := &Nod…