Go https://digest.evrone.ru/ ru Go 1.21, gonew и lego https://digest.evrone.ru/20230815 <img src="/sites/default/files/styles/card_m/public/2023-08/fgfdfbghgrfsgndh.png?itok=xxfSMzqE" width="960" height="540" alt="Go 1.21, gonew и lego" loading="lazy" typeof="Image" /> <br /> <p>В этом выпуске рассказываем про нововведения в языке Go, экспериментальную утилиту gonew, позволяющую создавать проект из шаблона, и альтернативную реализацию клиента Certbot.</p> <h2>Вышел Go 1.21</h2> <p>Не успели мы опомниться, а с момента выхода версии 1.20 прошло уже полгода. Пора смотреть, что нового в Go 1.21. Большинство изменений затронуло библиотеки, рантайм и инструментарий. Отдельное внимание разработчики уделили своему <a href="https://go.dev/doc/go1compat" rel=" noopener" target="_blank">обещанию</a> соблюдать обратную совместимость: приложения, созданные в соответствие со спецификацией первой версии языка, будут правильно компилироваться и работать в новых версиях.</p> <p>В Go 1.21 появилось три новых фичи. Первая добавляет функции min и max, вычисляющие наименьшее и наибольшее значение фиксированного числа аргументов упорядоченного типа. Гораздо проще объяснить, как это работает, <a href="https://tip.golang.org/ref/spec#Min_and_max" rel=" noopener" target="_blank">на примере кода</a>:</p> var x, y int m := min(x) // m == x m := min(x, y) // m is the smaller of x and y m := max(x, y, 10) // m is the larger of x and y but at least 10 c := max(1, 2.0, 10) // c == 10.0 (floating-point kind) f := max(0, float32(x)) // type of f is float32 var s []string _ = min(s...) // invalid: slice arguments are not permitted t := max("", "foo", "bar") // t == "foo" (string kind) <p>Вторая фича добавила универсальный «ластик», функцию clear. Она отлично справляется с двумя вещами: стирает всё содержимое из ассоциативных массивов (карт) или обнуляет все элементы среза. Учтите, что если карта или срез nil, то clear не работает.</p> <p>Третья фича — изменённый алгоритм инициализации пакетов. Теперь процесс инициализации сортирует все пакеты по пути импорта и итеративно повторяет это действие, пока список пакетов не опустеет. Вначале система находит первый пакет, для которого импорты инициализирован, затем инициализирует его и удаляет из списка. Учтите, что это может повлиять на поведение некоторых приложений, которые полагаются на определённый порядок инициализации.</p> <p>Помимо вышеперечисленного, функции теперь можно вызывать с аргументами, которые сами являются универсальными функциями. Так что теперь использовать универсальные функции можно без явного создания экземпляра, когда функция присваивается переменной (или возвращается в качестве значения результата).</p> <p>Это наиболее важные изменения релиза. Чтобы узнать подробности и ознакомиться с полным списком изменений, рекомендует прочитать <a href="https://go.dev/doc/go1.21" rel=" noopener" target="_blank">примечания к выпуску Go 1.21</a>.</p> <h2>Приложения из шаблонов</h2> <p>Любой писатель, хотя бы раз в жизни, сталкивался со страхом чистого листа. Открываешь текстовый редактор, заносишь руки над клавиатурой… и пустота. Ни мыслей, ни идей. Разработчики тоже довольно часто испытывают нечто подобное, когда создают новый проект.</p> <p>Конечно, можно начать с клонирования уже существующего проекта, но это не всегда наилучший способ приступить к работе. Чтобы решить эту проблему, можно обратиться к опыту всё тех же писателей. Если им раз за разом приходится создавать документы со схожей структурой, то для простоты они создают шаблоны документов. Эта фича есть во всех профессиональных текстовых редакторах. Так что вместо пустой страницы писатель видит уже готовый шаблон, что облегчает старт.</p> <p>Создание нового проекта приложения и создание нового документа концептуально не имеет отличий, так что использование шаблонов — отличный способ справиться с ситуацией. Поэтому был опубликован экспериментальный инструмент <a href="https://go.dev/blog/gonew" rel=" noopener" target="_blank">gonew</a>, позволяющий создавать проекты Go из заранее подготовленных шаблонов. Любой программист может создать такой шаблон, упаковать в виде модуля и сохранить для личного пользования или выложить в открытый доступ.</p> <p>Сразу оговоримся, что это пока только прототип, имеющий минимальную функциональность. Пощупать его своими руками можно после установки:</p> $ go install golang.org/x/tools/cmd/gonew@latest <p>В качестве шаблона можно взять заранее подготовленный<a href="https://pkg.go.dev/golang.org/x/example/helloserver" rel=" noopener" target="_blank"> пример</a>. В целом, создать собственный шаблон ничем не сложнее, чем создать любой другой модуль в Go. </p> <p>Чтобы создать проект по заданному шаблону достаточно вызвать gonew с двумя аргументами: путь к шаблону и имя модуля создаваемого проекта:</p> $ gonew golang.org/x/example/helloserver example.com/myserver $ cd ./myserver <p>Разработчики просят <a href="https://go.dev/s/gonew-feedback">сообщать</a> обо всех найденных ошибках, чтобы сделать работу gonew лучше и удобнее.</p> <h2>Конструктор LeGo</h2> <p>На Go делается много крутых и интересных приложений. Одно из них, библиотека <a href="https://github.com/go-acme/lego">lego</a>, выполняющее сразу две полезных функции: <a href="https://www.rfc-editor.org/rfc/rfc8555.html" rel=" noopener" target="_blank">ACME</a> (Automatic Certificate Management Environment) библиотека и удобный клиент для сервиса <a href="https://letsencrypt.org/" rel=" noopener" target="_blank">Let’s Encrypt</a>. Он полностью написан на Go и распространяется в виде исходников, предварительно скомпилированных пакетов и в виде Docker-контейнера.</p> <p>Краткая справка от Капитана Очевидность про Let’s Encrypt. Эта компания взяла на себя благородную миссию сделать современный интернет более защищённым и стала выдавать бесплатные TLS-сертификаты для сайтов. Имея такой сертификат, выпущенный центром сертификации Let’s Encrypt, для любого веб-сайта можно включить защищённый HTTPS-протокол и получить заветный символ закрытого замка в адресной строке.</p> <p>Это означает, что даже если трафик между узлами будет перехвачен злоумышленниками, то использовать они его не смогут. Весь передаваемый трафик шифруется криптографическими ключами, взлом которых, даже на современном железе, займёт тысячи лет. Звучит здорово, но теперь поговорим об ограничениях. Поскольку Let’s Encrypt бесплатен, сертификаты выдаются на ограниченное количество времени (90 дней). Если сертификат истёк, то его нужно перевыпустить.</p> <p>Для работы с Let’s Encrypt был разработан клиент <a href="https://certbot.eff.org/" rel=" noopener" target="_blank">Certbot</a>. С помощью него можно полностью контролировать процесс выпуска и перевыпуска сертификатов. Его активно применяют для автоматизации процесса, чтобы админам не приходилось вручную обновлять сертификаты каждые 90 дней. Certbot представляет собой реализацию ACME протокола, упомянутого выше. Альтернатив достаточно много, список доступен <a href="https://letsencrypt.org/docs/client-options/" rel=" noopener" target="_blank">на сайте проекта</a>.</p> <p>Основное, чем lego интересен для Go-разработчиков, это избавление от костылей в виде самодельной реализации ACME-протокола. Вся эта сложная работа уже была проделана за вас. Так что в вашем приложении может быть заложена функциональность работы с любыми центрами сертификации, поддерживающими этот протокол. Да и просто почитать код таких приложений полезно, там есть на что взглянуть.</p> <h2 id="article_title_7">Митапы</h2> Онлайн <h3>Go meetup</h3> <p>8 ноября 2023</p> <p>Осенью у нас запланирован Go Meetup. Программа мероприятия формируется, но регистрация уже открыта. Кстати, вы уже можете <a href="https://docs.google.com/forms/d/e/1FAIpQLSedDbmB8mAtDb5_bKgUnmh8f6apOYXDsdvtXt1JPz7VoWqX2A/viewform?usp=sf_link" rel=" noopener" target="_blank">подать доклад</a> прямо в режиме онлайн. Заявки на участие спикера принимаются до 15 октября.</p> <p>Интересуетесь нашими мероприятиями? В Telegram-канале <a href="https://t.me/meetups_evrone" rel=" noopener" target="_blank">Evrone meetups</a> мы выкладываем анонсы с подробными описаниями докладов, а также студийные записи прошедших митапов. Тем для кого выступать в новинку, мы оказываем всяческую поддержку и помогаем оформить экспертизу в яркое выступление. Подписывайтесь и пишите <a href="https://t.me/andrew_aquariuss" rel=" noopener" target="_blank">@andrew_aquariuss</a>, чтобы узнать подробности.</p> <p><a class="info-button" href="https://meetups.evrone.ru/golang-meetup-online-0?utm_source=digest_site&amp;utm_medium=transition&amp;utm_campaign=go_digest_8_2023" rel=" noopener" target="_blank">Регистрация</a></p> <h2 id="article_title_8">Вакансии</h2> <p>Удаленка / Офис</p> <h3>Evrone </h3> <p>Мы открыты для новых Go-разработчиков. В Evrone можно работать удалённо с первого дня, мы поддерживаем и оплачиваем участие в Open-source проектах и выступления на конференциях, а расти в грейдах можно с помощью честной системы проверки навыков и менторства.</p> <p><a class="info-button" href="https://jobs.evrone.ru/?utm_source=digest_site&amp;utm_medium=transition&amp;utm_campaign=go_digest_8_2023" rel=" noopener" target="_blank">Подробнее</a></p> <p> </p> Tue, 15 Aug 2023 10:15:52 +0000 Evrone digest /20230815 Вечеринка гоферов https://digest.evrone.ru/20230714 <img src="/sites/default/files/styles/card_m/public/2023-07/bnhmj.png?itok=sfxUUb1-" width="960" height="540" alt="Вечеринка гоферов" loading="lazy" typeof="Image" /> <br /> <p>Отвлекитесь от абстракций. Сегодня мы поговорим, как извлекать данные об оборудовании с помощью ghw, делать запросы в генеративные нейросети OpenAI и даже скачивать себе на компьютер больше оперативной памяти… серьёзно!</p> <h2>Читаем состав</h2> <p>Мы привыкли, что работаем с абстракциями. Это облегчает жизнь и позволяет лишний раз не думать о совместимости. Яркий пример — облака. Приложение работает внутри виртуальной машины или контейнера, а все вопросы совместимости ложатся на провайдера инфраструктуры. В случае с виртуальными машинами приложение думает, что работает на реальном процессоре и использует дисковый накопитель, в то время как оперирует лишь эмулированными представлениями. Всю низкоуровневую работу берёт на себя инфраструктура.</p> <p>Давайте отвлечёмся от привычного и посмотрим на небольшую библиотеку <a href="https://github.com/jaypipes/ghw" rel=" noopener" target="_blank">ghw (Golang HardWare)</a>. Её задача: определение и проверка работы оборудования. Она полностью поддерживает операционные системы Windows и Linux, а также частично macOS. Часть функций ghw работает без root-привилегий. Если какую-то часть информации считать не удалось, то библиотека не станет генерировать ошибку, а всего лишь выдаст warning message. Кстати, эти сообщения можно отключить через переменную окружения.</p> <p>Скажем сразу, что ghw не годится на роль системного монитора. Если надо собирать и анализировать метрики, вам подойдёт самый обычный Prometheus. Библиотека gwh нужна, чтобы собирать подробную информацию обо всех возможностях оборудования хоста. В качестве источников данных используются штатные утилиты операционной системы. Так, например, в Linux для получения информации о CPU используется /proc/cpuinfo, а для расширенных данных о сетевых адаптерах — ethtool.</p> <p>Вот пример запроса данных об установленных процессорах:</p> package main import ( "fmt" "math" "strings" "github.com/jaypipes/ghw" ) func main() { cpu, err := ghw.CPU() if err != nil { fmt.Printf("Error getting CPU info: %v", err) } fmt.Printf("%v\n", cpu) for _, proc := range cpu.Processors { fmt.Printf(" %v\n", proc) for _, core := range proc.Cores { fmt.Printf(" %v\n", core) } if len(proc.Capabilities) &gt; 0 { // pretty-print the (large) block of capability strings into rows // of 6 capability strings rows := int(math.Ceil(float64(len(proc.Capabilities)) / float64(6))) for row := 1; row &lt; rows; row = row + 1 { rowStart := (row * 6) - 1 rowEnd := int(math.Min(float64(rowStart+6), float64(len(proc.Capabilities)))) rowElems := proc.Capabilities[rowStart:rowEnd] capStr := strings.Join(rowElems, " ") if row == 1 { fmt.Printf(" capabilities: [%s\n", capStr) } else if rowEnd &lt; len(proc.Capabilities) { fmt.Printf(" %s\n", capStr) } else { fmt.Printf(" %s]\n", capStr) } } } } } <p>Пример вывода:</p> cpu (1 physical package, 6 cores, 12 hardware threads) physical package #0 (6 cores, 12 hardware threads) processor core #0 (2 threads), logical processors [0 6] processor core #1 (2 threads), logical processors [1 7] processor core #2 (2 threads), logical processors [2 8] processor core #3 (2 threads), logical processors [3 9] processor core #4 (2 threads), logical processors [4 10] processor core #5 (2 threads), logical processors [5 11] capabilities: [msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 popcnt aes lahf_lm pti retpoline tpr_shadow vnmi flexpriority ept vpid dtherm ida arat] <p>Получаемые данные можно сериализовать двумя способами: превратить в JSON или YAML. Для этого предусмотрены методы JSONString() и YAMLString(). Ещё одна полезная фича — возможность создания <a href="https://github.com/jaypipes/ghw/blob/main/SNAPSHOT.md" rel=" noopener" target="_blank">снапшотов</a>. Работает она пока только с Linux, а снапшоты представляют собой частичные копии деревьев /proc и /sys. В снапшот включаются только те данные, которые могут быть сняты при помощи ghw.</p> <h2>Играем с OpenAI</h2> <p>Только ленивый сейчас не говорит о продуктах OpenAI. Эта компания изначально была некоммерческим проектом, а ныне объединила усилия с Microsoft и получила от них внешнее финансирование. Множество разработок OpenAI уже были представлены общественности. Среди них чат-бот ChatGPT, генеративная нейросеть DALL-E, система распознавания голоса Whisper и большие языковые модели (LLM) GPT-3 и GPT-4.</p> <p>OpenAI даёт доступ к своим продуктам через собственное API и предоставляет документацию, позволяющую создавать приложения на их основе. Но вместо того, чтобы каждый раз создавать собственную «обёртку»‎, проще ‎воспользоваться готовой. Такой как <a href="https://github.com/sashabaranov/go-openai" rel=" noopener" target="_blank">go-openai</a>, содержащей неофициальные клиенты OpenAI API. Устанавливается стандартно, через go get:</p> go get github.com/sashabaranov/go-openai <p>Прежде чем использовать go-openai, нужно получить ключ доступа к API. Для этого надо зайти по адресу <a href="https://platform.openai.com/account/api-keys" rel=" noopener" target="_blank">https://platform.openai.com/account/api-keys</a>, cоздать аккаунт и сгенерировать секретный ключ на странице управления доступом. Помните, что ключ относится к чувствительным данным и его нельзя раскрывать третьим лицам. Теперь можно выполнять запросы, например:</p> <p> </p> package main import ( "context" "fmt" openai "github.com/sashabaranov/go-openai" ) func main() { client := openai.NewClient("your token") resp, err := client.CreateChatCompletion( context.Background(), openai.ChatCompletionRequest{ Model: openai.GPT3Dot5Turbo, Messages: []openai.ChatCompletionMessage{ { Role: openai.ChatMessageRoleUser, Content: "Hello!", }, }, }, ) if err != nil { fmt.Printf("ChatCompletion error: %v\n", err) return } fmt.Println(resp.Choices[0].Message.Content) } <h2>Жонглируем оперативной памятью</h2> <p>Помните знаменитое высказывание Билла Гейтса про то, что 640 КБ ОЗУ хватит всем? Шутить над ним, на самом деле, начали ещё до капитальных изменений порядка доступа к памяти в Windows NT. Чтобы запускать сложные приложения или игры, приходилось задействовать расширители памяти, вроде CWSDPMI. Это позволяло обходить существующие ограничения и использовать всю доступную оперативную память.</p> <p>Когда приложение не помещается в RAM, задействуется swap. Традиционно это файл или отдельный раздел на локальном дисковом накопителе. Без этого приложение прекратило бы работу, выдав ошибку. Размер swap-раздела может быть любым, но на практике он ограничивается объёмом локального диска. Недостатком swap на диске можно считать большое значение latency, в тысячи раз медленнее, чем с обычной ОЗУ. Концепция «всё есть файл» в Linux позволяет обойти и это ограничение, выполняя хранение данных swap не на локальном накопителе, а примонтировав часть оперативной памяти с другой машины.</p> <p>В основе проекта <a href="https://github.com/pojntfx/ram-dl" rel=" noopener" target="_blank">ram-dl</a> лежит <a href="https://github.com/pojntfx/go-nbd" rel=" noopener" target="_blank">go-nbd</a>, серверная часть и клиентская библиотека для управления сетевыми блочными устройствами. Объединив это с <a href="https://github.com/pojntfx/r3map" rel=" noopener" target="_blank">r3map</a>, библиотекой монтирования и миграции оперативной памяти, получаем уникальный инструмент, позволяющий расширить swap до любого размера. Это может пригодиться в разных сценариях: от тестирования до запуска специализированных приложений.</p> <p>Выглядит монтирование RAM следующим образом: на удалённой системе запускается серверная часть, которая резервирует участок памяти и делает его доступным по fRPC. Клиентская часть изменяет поведение команд mkswap, swapon и swapoff, заворачивая их на fRPC-бекэнд. На скоростных линиях связи производительность такого трюка будет сравнима с производительностью локального накопителя.</p> <h2>Интересно посмотреть</h2> <p>Пропустили наш предыдущий митап? Не страшно! Видеозаписи докладов уже выложены на нашем <a href="https://www.youtube.com/@EvroneDevelopment/" rel=" noopener" target="_blank">YouTube-канале</a> в кинематографическом качестве 4K и со студийным звуком.</p> <p>Подписывайтесь и ставьте 🔔колокольчик, чтобы получать уведомления о будущих трансляциях и видео! А ещё присоединяйтесь к <a href="https://t.me/meetups_evrone" rel=" noopener" target="_blank">Telegram-каналу</a> и будьте в курсе всех наших будущих мероприятий.</p> <h2 id="article_title_7">Митапы</h2> Онлайн <h3>Go meetup</h3> <p>13 сентября 2023</p> <p>Осенью у нас запланирован Go Meetup. Программа мероприятия формируется, но регистрация уже открыта. Кстати, вы уже можете <a href="https://docs.google.com/forms/d/e/1FAIpQLSedDbmB8mAtDb5_bKgUnmh8f6apOYXDsdvtXt1JPz7VoWqX2A/viewform?usp=sf_link" rel=" noopener" target="_blank">подать доклад</a> прямо в режиме онлайн. Заявки на участие спикера принимаются до 20 августа.</p> <p>Интересуетесь нашими мероприятиями? В Telegram-канале <a href="https://t.me/meetups_evrone" rel=" noopener" target="_blank">Evrone meetups</a> мы выкладываем анонсы с подробными описаниями докладов, а также студийные записи прошедших митапов. Тем для кого выступать в новинку, мы оказываем всяческую поддержку и помогаем оформить экспертизу в яркое выступление. Подписывайтесь и пишите <a href="https://t.me/andrew_aquariuss" rel=" noopener" target="_blank">@andrew_aquariuss</a>, чтобы узнать подробности.</p> <p><a class="info-button" href="https://meetups.evrone.ru/golang-meetup-online-1?utm_source=digest_site&amp;utm_medium=transition&amp;utm_campaign=go_digest_7_2023" rel=" noopener" target="_blank">Регистрация</a></p> <h2 id="article_title_8">Вакансии</h2> <p>Удаленка / Офис</p> <h3>Evrone </h3> <p>Мы открыты для новых Go-разработчиков. В Evrone можно работать удалённо с первого дня, мы поддерживаем и оплачиваем участие в Open-source проектах и выступления на конференциях, а расти в грейдах можно с помощью честной системы проверки навыков и менторства.</p> <p><a class="info-button" href="https://jobs.evrone.ru/?utm_source=digest_site&amp;utm_medium=transition&amp;utm_campaign=go_digest_7_2023" rel=" noopener" target="_blank">Подробнее</a></p> <p> </p> Fri, 14 Jul 2023 11:16:47 +0000 Evrone digest /20230714 Ископаемые реликвии https://digest.evrone.ru/20230620 <img src="/sites/default/files/styles/card_m/public/2023-06/vdfghkdjh.png?itok=8z6HKh5W" width="960" height="540" alt="Ископаемые реликвии" loading="lazy" typeof="Image" /> <br /> <p>Сегодняшний выпуск мы посвятили улучшению поддержки Go в мейнфреймах IBM, скриптовому языку Tamarin и проверке адресов электронной почты. Усаживайтесь поудобнее, наливайте чай и доставайте печеньки. Приятного чтения!</p> <h2>Go на z/OS</h2> <p>Поговорим о священном граале — мейнфреймах. Если спросить далёкого от этой темы человека, что такое мейнфрейм, то услышим что-то вроде: «Ну это такой очень большой и мощный сервер». Это верное определение, но вообще не дающее представления, насколько это производительная штука.</p> <p>Мейнфрейм жрёт невероятное количество электроэнергии и имеет внутри запредельное количество ресурсов. Как вам цифра в 200 ядер процессора собственной разработки с тактовой частотой 5.2 ГГц и 40 ТБ оперативной памяти? Речь о мейнфрейме IBM z16 построенном на чипах IBM Telum и представленном в 2021 году.</p> <p>Кому нужны эти проприетарные динозавры, стоящие до $4 млн за штуку да ещё и с помесячной оплатой за процессорное время? Ответ прост: банкам, биржам, крупным производствам, телекоммуникационным компаниям и государственным ведомствам (по сути всем, кому нужна высочайшая надёжность, отказоустойчивость и безопасность).</p> <p>Мейнфреймы — это даже не пресловутые «пять девяток» аптайма. У них «семь девяток», то есть 99.9999999% или максимум 3 секунды простоя в год. Заявляются такие SLA, как 9 мс на обработку транзакции. Вспомните об этом, когда будете платить за кофе банковской карточкой. За эти 9 мс платёжная система успеет проверить, что ваша операция не содержит признаков фрода и завершит транзакцию.</p> <p>Ещё мейнфреймы — это про обратную совместимость. Она возведена в абсолют настолько, что софт, созданный 30 лет, спокойно запустится и на современном мейнфрейме. Вот мы и подошли к новости, ради которой пришлось написать столь длинное вступление. IBM <a href="https://community.ibm.com/community/user/ibmz-and-linuxone/blogs/james-tang1/2023/05/26/ibm-open-enterprise-sdk-for-go-120-is-now-availabl" rel=" noopener" target="_blank">сообщила</a> о выходе Open Enterprise SDK для Go 1.20. В нём есть инструмент, позволяющий автоматически портировать исходники Go для запуска на мейнфреймах под управлением z/OS.</p> <p>Prometheus для z/OS желаете? Легко! Перенести собственное приложение? Тоже не составит труда. Делается это с помощью утилиты <a href="https://github.com/ZOSOpenTools/wharf" rel=" noopener" target="_blank">Wharf</a> с открытым исходным кодом. Да, да… вы не ослышались – консервативный гигант уже второй год подряд пополняет свой репозиторий <a href="https://github.com/orgs/ZOSOpenTools/" rel=" noopener" target="_blank">ZOSOpenTools</a> и прилагает усилия чтобы как можно больше разработчиков смогли портировать свои приложения на z/OS.</p> <p>Портирование с Wharf выглядит весьма удобным. Инструмент создаёт отдельное рабочее пространство (workspace) и начинает исследовать код, выявляя участки, которые точно сломаются при сборке на z/OS. Найденные ошибки Wharf автоматически исправляет, расставляет, где нужно, тег «zos» и заносит все сделанные изменения в лог. Есть также ручной режим, позволяющий самостоятельно принимать решение о внесении изменений.</p> <p>Автоматическое портирование иногда не срабатывает. Система умеет решать большинство рутинных задач, но если сталкивается с неразрешимой проблемой, то передаёт управление пользователю. Так что какие-то пакеты придётся портировать ручками. Несмотря на это, инструмент выглядит логичным и правильным шагом к дальнейшему развитию экосистемы z/OS. Так что Go-разработчикам стоит учитывать, что их приложения могут быть перенесены на мейнфреймы IBM.</p> <h4> </h4> <h2>Tamarin 2.0.0 Alpha</h2> <p>Множество волшебных сказок имеют один и тот же сюжет: «Поди туда — не знаю куда, принеси то — не знаю что». Разработчика этим не напугать, ведь они привыкли создавать то, чего ещё нет. Так произошло и с Tamarin – скриптовым языком для проектов на Go. В нём автор реализовал всё то, чего в Go не было и появиться в обозримом будущем вряд ли могло.</p> <p>Началось всё с книги <a href="https://interpreterbook.com/" rel=" noopener" target="_blank">Writing An Interpreter In Go</a>, которую написал software-инженер Торстен Болл (Thorsten Ball). В ней он рассказывает, как с нуля разработать свой язык программирования. На примере абстрактного Monkey programming language он последовательно демонстрирует, как без сторонних библиотек разобраться с абстрактным синтаксическим деревом, лексическим анализом и парсингом. Задумка отличная: пока решаешь конкретные задачи, начинаешь понимать процессы на более низком уровне.</p> <p>История умалчивает, как эта книга попала к автору Tamarin, Кёртису Мизи (Curtis Myzie). Но в ней он явно увидел способ запилить собственный «обезьяний» язык. Название «Tamarin» было выбрано не случайно, поскольку это маленькие прикольные приматы из семейства игрунковых. В этом скриптовом языке было реализовано много фишек из других языков, таких как Rust и Python. Вот пример кода, фактически смеси из Go и Python, с пайпами и обращением к частям стандартной библиотеки Go:</p> array := ["gophers", "are", "burrowing", "rodents"] sentence := array | strings.join(" ") | strings.to_upper print(sentence) <p>Этот код выводит фразу:</p> GOPHERS ARE BURROWING RODENTS <p>Первая версия работала достаточно медленно. Но автор Tamarin подумал о производительности, спросите вы? Нет, просто у Торстена Болла вышла ещё одна книжка <a href="https://compilerbook.com/" rel=" noopener" target="_blank">Writing A Compiler In Go</a>, а за ней случились и доработки.</p> <p>В июне 2023 увидела свет альфа-версия Tamarin v2.0.0, которая обзавелась компилятором и одноимённой виртуальной машиной. За счёт этого удалось добиться радикального увеличения производительности. Tamarin v2 даже в альфа-версии работает в 127 раз быстрее, чем v1. Описанные в книге методы сработали идеально.</p> <p>Боимся предположить, что произойдёт, если Торстен Болл выпустит книгу «Becoming a Dark Lord in Go» 😀</p> <h2>Верификация email без отправки писем</h2> <p>Канули в лету те славные времена, когда можно было сотнями создавать фальшивые аккаунты в чатах и на форумах, вводя любые несуществующие email-адреса. Сейчас при регистрации почти на любом интернет-ресурсе попросят перейти по ссылке из письма или ввести код. Если не сделать этого в течение какого-то промежутка времени, то новый аккаунт блокируется. Этот механизм помогает отсеивать недействительные адреса и держать базу контактов в чистоте.</p> <p>Но это точно не значит, что фейковых регистраций нет. Их может быть много, что создаёт нагрузку на основную базу данных ресурса и на почтовые сервисы. Встаёт интересная задача определять валидность и существование почтового ящика ещё до завершения регистрации. Подводных камней на этом пути множество. Вот, например, для первого этапа проверки есть спецификация, отражённая в соответствующем <a href="https://datatracker.ietf.org/doc/html/rfc822" rel=" noopener" target="_blank">RFC 822</a> и даже готовые монструозные регулярки, вроде <a href="http://www.ex-parrot.com/~pdw/Mail-RFC822-Address.html" rel=" noopener" target="_blank">таких</a>.</p> <p>Но как только начинаешь изучать RFC, открываются врата ада. Спецификация одобряет различную экзотику, до которой обычному пользователю додуматься сложно. Самый простой пример: по RFC пробел в адресе — это нормально. Например, вот такой адрес формально соответствует спецификации:</p> "Jane Doe"@example.com <p>Если бы Джон Коннор был ирландцем, то вполне возможно завёл бы себе почтовый адрес с апострофом (но без кавычек), строго по RFC:</p> John.O'Connor@example.com <p>И это лишь начало спуска в кроличью нору. В 2014 году на Хабре была прекрасная <a href="https://habr.com/ru/articles/224623/" rel=" noopener" target="_blank">статья</a> на эту тему. </p> <p>Переходим ко второму акту Мерлезонского балета, а именно к проверке адреса на существование. Здесь используется сразу несколько приёмов:</p> <ul> <li aria-level="1">lookup через SMTP;</li> <li aria-level="1">проверка MX-записей в DNS;</li> <li aria-level="1">валидация через бесплатных email-провайдеров;</li> <li aria-level="1">проверка не является ли адрес одноразовым (Disposable Email Address).</li> </ul> <p>И тут, наконец-то, станет полегче. Чтобы не изобретать велосипед, Go-разработчикам возьмите на вооружение библиотеку <a href="https://github.com/AfterShip/email-verifier" rel=" noopener" target="_blank">email-verifier</a>. В ней уже реализованы все вышеперечисленные способы проверки. Так что вылезайте из кроличьей норы, а в освободившееся время заглядывайте на наш <a href="https://www.youtube.com/@EvroneDevelopment" rel=" noopener" target="_blank">YouTube-канал</a>.</p> <h2>Немного IT</h2> <p><a href="https://www.youtube.com/channel/UCzjQIaveGe_G8yT9iFcKwTQ/featured" rel=" noopener" target="_blank">Подкаст про Go</a> снимают и развивают двое наших коллег из Evrone.  Они обсуждают его преимущества и недостатки, сравнивают с другими языками. <a href="https://someit.tech/" rel=" noopener" target="_blank">Сайт проекта</a>.</p> <p>Выпуски длятся 50-70 минут, а значит можно совместить какие-нибудь скучные занятия с обучением. Отличная возможность погрузится в нюансы Go, стоя в пробке или проезжая очередную станцию метро!</p> <p>Ну а если вам есть что сказать — добро пожаловать в <a href="https://someit.tech/">комментарии</a>!</p> <h2 id="article_title_7">Митапы</h2> Онлайн <h3>Go meetup</h3> <p>13 сентября 2023</p> <p>Осенью у нас запланирован Go Meetup. Программа мероприятия формируется, но регистрация уже открыта. Кстати, вы уже можете <a href="https://docs.google.com/forms/d/e/1FAIpQLSedDbmB8mAtDb5_bKgUnmh8f6apOYXDsdvtXt1JPz7VoWqX2A/viewform?usp=sf_link" rel=" noopener" target="_blank">подать доклад</a> прямо в режиме онлайн. Заявки на участие спикера принимаются до 20 августа.</p> <p>Интересуетесь нашими мероприятиями? В Telegram-канале <a href="https://t.me/meetups_evrone" rel=" noopener" target="_blank">Evrone meetups</a> мы выкладываем анонсы с подробными описаниями докладов, а также студийные записи прошедших митапов. Тем для кого выступать в новинку, мы оказываем всяческую поддержку и помогаем оформить экспертизу в яркое выступление. Подписывайтесь и пишите <a href="https://t.me/andrew_aquariuss" rel=" noopener" target="_blank">@andrew_aquariuss</a>, чтобы узнать подробности.</p> <p><a class="info-button" href="https://meetups.evrone.ru/golang-meetup-online-1?utm_source=digest_site&amp;utm_medium=transition&amp;utm_campaign=go_digest_6_2023" rel=" noopener" target="_blank">Регистрация</a></p> <h2 id="article_title_8">Вакансии</h2> <p>Удаленка / Офис</p> <h3>Evrone </h3> <p>Мы открыты для новых Go-разработчиков. В Evrone можно работать удалённо с первого дня, мы поддерживаем и оплачиваем участие в Open-source проектах и выступления на конференциях, а расти в грейдах можно с помощью честной системы проверки навыков и менторства.</p> <p><a class="info-button" href="https://jobs.evrone.ru/?utm_source=digest_site&amp;utm_medium=transition&amp;utm_campaign=go_digest_6_2023" rel=" noopener" target="_blank">Подробнее</a></p> <p> </p> Tue, 20 Jun 2023 10:42:39 +0000 Evrone digest /20230620 Модульный монолит https://digest.evrone.ru/20230518 <img src="/sites/default/files/styles/card_m/public/2023-05/sdfgdhf.png?itok=eGOl_O5R" width="960" height="540" alt="Модульный монолит" loading="lazy" typeof="Image" /> <br /> <p>В нашем майском Go-дайджесте мы задумались о низкоуровневых задачах и собственном Git-сервере с блэкджеком и хуками. А ещё изучили подходы к структурированию проектов на Go и нашли слово moduliths в словаре Google.</p> <h2>Пишем бутлоадер</h2> <p>Иногда мы слышим, что на Go пишут хипстеры, а чтобы создать что-то значимое, нужен язык C. Аргументируют так: Windows, Linux и macOS написаны на C, а ваш этот новомодный Go годится лишь для высокоуровневых вещей. Сегодня постараемся опровергнуть это.</p> <p>Любые персональные компьютеры имеют BIOS или UEFI в качестве базовой микропрограммы. они взаимодействуют с железом на самом низком уровне, а также передают управление загрузчику операционной системы. Сложность заключается в том, что обе этих системы не совместимы друг с другом. Благо, существует универсальный загрузчик GRUB, который совместим и с BIOS, и c UEFI.</p> <p>Портировать его на Go будет сложно по множеству причин. Первое, что приходит на ум — стандарт мультизагрузки требует размещения специальной структуры в первых 4 Kб бинарника. Но у Go бинарник даже в пустом виде будет весить 5 Kб. Альтернативой GRUB могут быть BOOTBOOT и Limine. Они не поддерживают старые 32-битные ядра, но с современными 64-битными никаких сложностей нет. При этом оба умеют запускать бинарники в формате ELF c нативной поддержкой go build (через настройку GOOS=linux).</p> <p>Расковырять BOOTBOOT и заставить его плясать традиционный гоферский танец — задача не самая простая. Начать стоит с поиска места, где происходит волшебство, а именно выполнения первой настоящей инструкции процессора в коде Go. Всё начинается с ассемблерной функции _rt0_GOOS_GOARCH в одноимённом файле. Но мы же собрались писать на Go, а не на языке ассемблера. Наверное, стоит написать простую функцию, вроде такой и поставить на неё флаг, указывающий, что это начало приложения:</p> func _start(){ // Code goes here for { /* loop forever */ } } <p>Вроде бы всё просто и с помощью флага -E можно добиться желаемого. Но сразу же появляется проблема. Что Limine, что BOOTBOOT требуют специального формата ELF-бинарника. Этот формат создаётся с помощью скриптов компоновщика… которые компоновщик Go не поддерживает.</p> <p>Придётся прибегнуть к хитрости и скрестить ежа с ужом, то есть стандартный Go-компилятор со сторонним компоновщиком (например, из GCC). Опустим процесс установки GCC для разных архитектур и операционных систем, сосредоточившись на подключении компоновщика:</p> -ldflags="-linkmode external \ -extld x86_64-elf-ld \ -extldflags '-nostdlib -n -v -static -m elf_x86_64 -T link.ld'" <p>Это лишь начало сложного и долгого пути. Если вам интересно узнать, как разобраться с cgo, что такое прагмы и какой недокументированный флаг надо передать при сборке, то все ответы вы найдёте в статье <a href="https://totallygamerjet.hashnode.dev/writing-an-os-in-go-the-bootloader" rel=" noopener" target="_blank">Writing an OS in Go: The Bootloader</a>.</p> <h2>Self-hosted GIT</h2> <p>Причин завести свой небольшой клон Github может быть много. Это удобно, позволяет самостоятельно контролировать свои данные. Можно получить независимость от конкретного поставщика сервиса, но продолжать пользоваться базовыми возможностями Git.</p> <p>Сначала подумайте, нужен ли вам self-hosted вообще? За сохранность данных вы отвечаете самостоятельно, но и обслуживание, поддержка сервера также становится вашей задачей. Для обеспечения защиты от несанкционированного доступа потребуется регулярно обновлять программное обеспечение. Ну а чтобы предотвратить потерю данных в случае сбоя, регулярно делать резервные копии.</p> <p>Но давайте всё-таки о том, как без особых усилий такой локальный Git создать. На помощь приходят те же ребята, которые создали BubbleTea и Wish. Мы <a href="https://digest.evrone.ru/20230118">рассказывали</a> об этих инструментах в одном из прошлых дайджестов. Их Git-сервер называется <a href="https://github.com/charmbracelet/soft-serve" rel=" noopener" target="_blank">Soft Serve</a> и прекрасно работает прямо из командной строки:</p> <p><img alt="Soft Serve" data-entity-type="file" data-entity-uuid="a5212831-5d97-4712-8cfa-0978ba019645" width="1214" height="623" loading="lazy" class="lazyload" data-src="/sites/default/files/inline-images/image1_6.png" /></p> <p>Весь Git-сервер представляет собой один бинарник, который после запуска создаёт директорию data, где будет хранить репозитории, ключи и базу данных. При первом запуске потребуется определить переменную окружения SOFT_SERVE_INITIAL_ADMIN_KEYS. Любой ключ, добавленный в эту переменную, будет считаться ключом администратора и иметь полный набор разрешений для выполнения любых действий.</p> <p>Используя эту переменную, Soft Serve создаст пользователя admin. Потом его можно будет переименовать или изменить настройки профиля. Также при первом запуске внутри директории data будет создан конфигурационный файл config.yaml с настройками сервера. Там можно кастомизировать базовые настройки, такие как используемые порты. Ну а управление репозиториями осуществляется из консоли с помощью команды repo.</p> <p>Soft Serve имеет поддержку стандартных хуков git и кастомных хуков. Они могут работать глобально для всех репозиториев (удобно для выстраивания цепочек CI/CD) или быть заданы для конкретных репозиториев. По нашему мнению, это отличный инструмент, который достоин быть в арсенале разработчиков и DevOps-инженеров. А если хотите пощупать своими руками его текстовый UI, то просто подключитесь к демонстрационной версии по SSH:</p> ssh git.charm.sh -t soft-serve <h2>В поисках лучшей структуры</h2> <p>Если о своём опыте рассказывают международные компании, такие как <a href="https://www.humansecurity.com/" rel=" noopener" target="_blank">HUMAN Security</a>, обычно это попадает в best practices. Недавно в блоге израильского software-инженера Авива Карми (Aviv Carmi) были выложены две части статьи, посвящённых поиску лучшей структуры для проекта на Go. Это вторая серьёзная попытка выбрать подход к структурированию кода. Первая была сделана 4 года назад и изложена в статье <a href="https://avivcarmi.com/ok-lets-go-three-approaches-to-structuring-go-code/" rel=" noopener" target="_blank">OK Let’s Go: Three Approaches for Structuring Go Code</a>.</p> <p>Если времени читать нет, то суть сводится к тому, что есть три основных подхода:</p> <ol> <li aria-level="1">Single Package — вся кодовая база лежит в одной директории, никаких отдельных пакетов не создаётся.</li> <li aria-level="1">Coupled Packages — разбиваем код на пакеты, единолично отвечающие за некоторое определённое поведение. Пакеты взаимодействуют друг с другом и знают друг о друге. Гарантируется, что каждая часть логики полностью реализована в отдельном пакете.</li> <li aria-level="1">Independent Packages — полностью независимые пакеты, которые, как и в предыдущем подходе, взаимодействуют друг с другом, но ничего не знают друг о друге. Для каждого сервиса пакет объявляет собственный интерфейс.</li> </ol> <p>Теперь на эти подходы автор взглянул с высоты накопленного опыта. Он с командой пытался достичь двух глобальных целей: структурной согласованности, а также разделения бизнес-логики и инфраструктуры. Второе нужно было ради тестируемости, гибкости и улучшенных возможностей управления проектами.</p> <p>Приглядимся к трём указанным подходам, чтобы понять помогают ли они достичь целей. Single Package лёгкий и простой, но фактическое отсутствие структуры и разделения ответственности лишает адекватного управления. Если оставить его только для небольших проектов, то по мере их роста придётся часто выполнять миграции на более сложные структуры. Небольшие проекты имеют особенность вырастать на глазах, словно шерсть у кота после похода к грумеру.</p> <p>Coupled Packages поможет достичь обеих исходных целей, но использование глобальных переменных и взаимосвязь пакетов будет негативно влиять на возможность повторного использования. </p> <p>Третий же подход Independent Packages тоже годится, а благодаря полной независимости пакетов, компоненты можно безопасно переносить или копировать между проектами. Ценой станет необходимость написания и поддержки большего количества интерфейсов. </p> <p>В HUMAN Security решили остановиться на Coupled Packages. Спустя несколько лет написания проектов на основе этого подхода провели ретроспективный анализ и осознали, что это было хорошее, но не лучшее решение. Детали вы найдёте в <a href="https://avivcarmi.com/finding-the-best-go-project-structure-part-1/" rel=" noopener" target="_blank">первой</a> и <a href="https://avivcarmi.com/finding-the-best-go-project-structure-part-2/" rel=" noopener" target="_blank">второй</a> частях оригинальной статьи.</p> <h2>Фреймворк Service Weaver</h2> <p>Забавную попытку усидеть на двух стулья сразу сделала Google, выпустив фреймворк Service Weaver. Представьте, что вы разрабатываете приложение так, словно оно монолит, но при этом у вас есть магическая кнопка, позволяющая распределить его по кластеру микросервисов. Они даже термин соответствующий придумали — moduliths, сокращение от слов modular monoliths. По замыслу авторов такая штука заполнит пробел между монолитом и микросервисами.</p> <p>На бумаге всё выглядит замечательно. Фреймворк оперирует компонентами, которые могут взаимодействовать друг с другом, но при этом очень мало знают друг о друге. Чем-то напоминает отношения покупателей и продавцов на Авито. Обычный интерфейс Go становится контрактом компонента, например: </p> type Reverser interface { Reverse(context.Context, string) (string, error) } <p>При этом у каждого компонента есть одна или несколько реализаций:</p> //go:generate go run github.com/ServiceWeaver/weaver/cmd/weaver@latest generate type reverser struct { weaver.Implements[Reverser] } // Reverse is a concrete implementation of the Reverser interface func (r *reverser) Reverse(ctx context.Context, s string) (string, error) { // concrete implementation } <p>Здесь видно встраивание weaver.Implements[Reverser] в reverser. Может показаться, что нарушены все принципы интерфейсов, гласящие, что интерфейсы не должны знать друг о друге. Не всё так просто. В Service Weaver это служит триггером для генератора кода, который сделает основную магию. При запуске приложения (словно это монолит) он сделает локальную заглушку и привяжет Reverser к reverser конкретной реализации. Затем перенаправит все вызовы методов.</p> <p>Когда мы захотим раскидать компоненты на микросервисы, вызов метода Reverse(...) из Reverser фактически превратится в цепочку:</p> <ul> <li aria-level="1">сериализация ввода;</li> <li aria-level="1">выполнение сетевого вызова;</li> <li aria-level="1">десериализация на другой стороне;</li> <li aria-level="1">выполнение действия;</li> <li aria-level="1">возврат ответа по этой же цепочке.</li> </ul> <p>Также будут инициализированы зависимости компонентов, то есть определённые локальные или сетевые прокси в зависимости от способа развёртывания. Таким образом, фреймворк Service Weaver — это гибрид из генератора кода, сетевого прокси и контейнера внедрения зависимостей (DI). Хотите узнать детали? Тогда советуем прочитать статью Преслава Рачева (Preslav Rachev) — <a href="https://preslav.me/2023/05/12/golang-dependency-injection-in-google-service-weaver/" rel=" noopener" target="_blank">Digging into Service Weaver: Dependency Injection</a>.</p> <h2 id="article_title_7">Митапы</h2> Онлайн <h3>Go meetup</h3> <p>14 июня 2023</p> <p>Совсем скоро мы встретимся на Go Meetup. Программа мероприятия формируется, но регистрация уже открыта. Кстати, вы уже можете <a href="https://docs.google.com/forms/d/e/1FAIpQLSedDbmB8mAtDb5_bKgUnmh8f6apOYXDsdvtXt1JPz7VoWqX2A/viewform?usp=sf_link" rel=" noopener" target="_blank">подать доклад</a> прямо в режиме онлайн. Заявки на участие спикера принимаются до 25 мая.</p> <p>Интересуетесь нашими мероприятиями? В Telegram-канале <a href="https://t.me/meetups_evrone" rel=" noopener" target="_blank">Evrone meetups</a> мы выкладываем анонсы с подробными описаниями докладов, а также студийные записи прошедших митапов. Тем для кого выступать в новинку, мы оказываем всяческую поддержку и помогаем оформить экспертизу в яркое выступление. Подписывайтесь и пишите <a href="https://t.me/andrew_aquariuss" rel=" noopener" target="_blank">@andrew_aquariuss</a>, чтобы узнать подробности.</p> <p><a class="info-button" href="https://meetups.evrone.ru/go-meetup-online-2?utm_source=digest_site&amp;utm_medium=transition&amp;utm_campaign=go_digest_5_2023" rel=" noopener" target="_blank">Регистрация</a></p> <h2 id="article_title_8">Вакансии</h2> <p>Удаленка / Офис</p> <h3>Evrone </h3> <p>Мы открыты для новых Go-разработчиков. В Evrone можно работать удалённо с первого дня, мы поддерживаем и оплачиваем участие в Open-source проектах и выступления на конференциях, а расти в грейдах можно с помощью честной системы проверки навыков и менторства.</p> <p><a class="info-button" href="https://jobs.evrone.ru/?utm_source=digest_site&amp;utm_medium=transition&amp;utm_campaign=go_digest_5_2023" rel=" noopener" target="_blank">Подробнее</a></p> <p> </p> Thu, 18 May 2023 11:59:10 +0000 Evrone digest /20230518 Made in … https://digest.evrone.ru/20230418 <img src="/sites/default/files/styles/card_m/public/2023-04/frhrtyhgwfq.png?itok=G-AF-Aw2" width="960" height="540" alt="Made in …" loading="lazy" typeof="Image" /> <br /> <p>В нашем сегодняшнем дайджесте не будет особенностей языка, библиотек и фреймворков. Предлагаем повысить насмотренность и взглянуть на приложения, созданные с помощью Go. В нашем меню: аналог MongoDB, приложение для превращения команд CLI в видео или гифку, а также порт модели LLaMa GPT.</p> <h2>FerretDB GA 1.0 released</h2> <p>«Свято место пусто не бывает» — эта поговорка актуальна во все времена. MongoDB создавалась как приложение с открытым исходным кодом, лицензируемым под GNU AGPL. Языковые драйверы распространялись по лицензии Apache. Инновация в чистом виде и одно из самых простых решений на рынке. MongoDB было легко использовать, она обладала качественной документацией и получила заслуженное внимание со стороны разработчиков.</p> <p>Осенью 2018 года создатели MongoDB плотно занялись монетизацией своего продукта, отодвинув на задний план интересы сообщества open source. Copyleft-лицензия AGPL была заменена на SSPL, что сделало нецелесообразным создание DBaaS-версий MongoDB. Единственным вариантом оставалось приобретать коммерческую лицензию, что было невыгодно многим облачным провайдерам. Также они сделали собственную облачную версию MongoDB Atlas, работающую в рамках мультиоблака из AWS, Azure и GCP.</p> <p>Естественной реакцией разработчиков открытого ПО стало создание полностью свободной альтернативы MongoDB. Проект получил название <a href="https://www.ferretdb.io/" rel=" noopener" target="_blank">FerretDB</a>. Он представляет собой stateless-прокси и преобразует протокол MongoDB в SQL, а в качестве движка использует PostgreSQL. Такая архитектура даёт совместимость с существующими драйверами MongoDB и позволяет использовать FerretDB в качестве полноценной замены. Это решение подойдёт и обычным пользователям, и облачным провайдерам для построения DBaaS-решений. </p> <p>FerretDB создавался с упором на совместимость и производительность. Оригинальная MongoDB была разработана на «плюсах». FerretDB в качестве стека выбрал чистый Golang. Привычные инструменты, такие как <a href="https://www.mongodb.com/docs/mongodb-shell/" rel=" noopener" target="_blank">mongosh</a>,<a href="https://www.mongodb.com/products/compass" rel=" noopener" target="_blank"> MongoDB Compass</a>,<a href="https://nosqlbooster.com/" rel=" noopener" target="_blank"> NoSQL Booster</a> или<a href="https://mingo.io/" rel=" noopener" target="_blank"> Mingo</a> спокойно воспримут FerretDB и будут работать с ним, как с нативной инсталляцией MongoDB. Забавно, но гиганты вроде SAP сейчас работают над поддержкой FerretDB в HANA. Подробности читайте<a href="https://blog.ferretdb.io/ferretdb-1-0-ga-opensource-mongodb-alternative/" rel=" noopener" target="_blank"> в блоге проекта</a>.</p> <h2>CLI хоум видео</h2> <p>Создание визуальных материалов – это целое искусство. Особенно, если речь идёт о скучных командах консоли. Конечно, записать небольшой скринкаст и слепить из него гифку сможет любой технический писатель. Но хочется идеально, красиво и без запинок. Чтобы размер получившегося файла был адекватный, а качество приемлемым. К счастью, такой инструмент существует, называется VHS. Название полностью отражает смысл и воркфлоу. Вначале надо создать «кассету», затем записать на неё серию команд и пауз, вставить в проигрыватель и на выходе получить красоту.</p> <p><a href="https://github.com/charmbracelet/vhs#installation" rel=" noopener" target="_blank">Инструкция по установке</a> VHS доступна в<a href="https://github.com/charmbracelet/vhs" rel=" noopener" target="_blank"> репозитории</a> проекта на GitHub. Поддерживаются практически все операционные системы (Windows, Linux, macOS). Единственное, что слегка портит впечатление – приложение тянет за собой приличное количество зависимостей. Также VHS можно запустить внутри Docker-контейнера (сразу вместе со всеми зависимостями). После того, как VHS установлен, советуем сразу ознакомиться с коротким мануалом по командам: </p> vhs manual <p>Теперь можно приступать к подготовке нашей «кассеты». В Linux это будет выглядеть приблизительно так: </p> touch demo.tape nano demo.tape <p>Теперь вводим команды, по которым будет пробегать терминал, формируя нужную нам GIF. В начале файла задаём формат вывода и некоторые настройки, а только потом команды, например: </p> # Where should we write the GIF? Output demo.gif # Set up a 1200x600 terminal with 46px font. Set FontSize 46 Set Width 1200 Set Height 600 # Type a command in the terminal. Type "echo 'Welcome to VHS!'" # Pause for dramatic effect... Sleep 500ms # Run the command by pressing enter. Enter # Admire the output for a bit. Sleep 5s <p>Сохраняем эту последовательность и запускаем файл на рендер: </p> vhs demo.tape <p>Поскольку в качестве выходного файла мы задали наименование demo.gif, этот файл появится в папке, откуда мы делали вызов:</p> <p><img alt="demo.gif" data-entity-type="file" data-entity-uuid="b966e21a-9686-459f-8c83-7edde1394500" width="740" height="560" loading="lazy" class="lazyload" data-src="/sites/default/files/inline-images/ewtryheuj.gif" /></p> <p>Таким образом можно «на лету» создавать учебные и иллюстрационные материалы для баз знаний и статей. Помимо создания файлов «кассет» вручную, можно воспользоваться записью команд:</p> vhs record &gt; cassette.tape <p>Приложение самостоятельно запишет все вводимые в терминале команды в файл. Его можно будет «причесать» вручную, проставив все необходимые паузы.</p> <p>Отдельно стоит отметить, что получаемые файлы будут очень небольшого размера. Гифка выше занимает всего 84 Кбайта. Поскольку VHS создан на Golang, его можно кастомизировать, как душа пожелает. Репозиторий открыт всем желающим, так что не поленитесь поставить «звездочку» и взять на вооружение этот прекрасный инструмент.</p> <h2>LLaMA GPT на Go</h2> <p>Большие GPT-модели совершили прорыв и теперь удивляют нас своими способностями. Проблема лишь в том, что запустить такую модель на обычном компьютере не выйдет. Речь даже не об одном GPU, а о кластере из GPU, который позволит загрузить всю модель в VRAM и уже после этого приступать к работе. Поэтому такие модели крутятся где-то в дата-центрах по всему миру, а мы покупаем к ним временный доступ. Но что если хочется локальное решение, пускай даже оно не будет идеальным?</p> <p>Такое решение есть — LLaMA. Эта модель была представлена в феврале 2023 года, обучена на 20 языках и существует в четырёх версиях:</p> <ol> <li aria-level="1">LLaMA-7B,</li> <li aria-level="1">LLaMA-13B, </li> <li aria-level="1">LLaMA-33B, </li> <li aria-level="1">LLaMA-65B.</li> </ol> <p>Цифра в названии означает количество параметров (в млрд). Изначально её хотели предоставлять исключительно научным и учебным организациям, но волей судеб слили на торренты. С тех пор она стала доступна всем желающим. Самый известный и часто упоминаемый порт был создан на чистом С/С++ болгарским программистом Георгием Гергановым (Georgi Gerganov). Познакомиться с исходным кодом можно в <a href="https://github.com/ggerganov/llama.cpp" rel=" noopener" target="_blank">репозитории</a> проекта.</p> <p>Мечтой большинства ML-хакеров стало вникнуть в суть (на сленге это называется «грокнуть») больших языковых моделей, не тратя кучу денег, используя лишь простое оборудование. Идея отказа от GPU легла в основу порта <a href="https://github.com/gotzmann/llama.go" rel=" noopener" target="_blank">llama.go</a>, созданного программистом Сергеем Гоцуляком (Serge Gotsuliak).</p> <p>Кросс-платформенность, поддержка всех существующих моделей LLaMA и первый стабильный <a href="https://github.com/gotzmann/llama.go/releases/tag/v1.0.0" rel=" noopener" target="_blank">релиз</a> — всё это лишь начало пути. Дальше запланирована разработка чата в реальном времени (аля ChatGPT), автозагрузка конвертированных моделей весов из интернета, увеличение скорости за счёт поддержки инструкций AVX2 и INT8-квантование, дабы большие модели помещались в тот же объём памяти. Работы — непочатый край, так что не забудьте поддержать автора звёздочкой.</p> <h2 id="article_title_7">Митапы</h2> Онлайн <h3>Go meetup</h3> <p>14 июня 2023</p> <p>Летом мы встретимся на Go Meetup. Программа мероприятия формируется, но регистрация уже открыта. Кстати, вы уже можете <a href="https://forms.gle/svgvCCxM7cRTL3wX7" rel=" noopener" target="_blank">подать доклад</a> прямо в режиме онлайн. Заявки на участие спикера принимаются до 25 мая.</p> <p>Интересуетесь нашими мероприятиями? В Telegram-канале <a href="https://t.me/meetups_evrone" rel=" noopener" target="_blank">Evrone meetups</a> мы выкладываем анонсы с подробными описаниями докладов, а также студийные записи прошедших митапов. Тем для кого выступать в новинку, мы оказываем всяческую поддержку и помогаем оформить экспертизу в яркое выступление. Подписывайтесь и пишите <a href="https://t.me/andrew_aquariuss" rel=" noopener" target="_blank">@andrew_aquariuss</a>, чтобы узнать подробности.</p> <p><a class="info-button" href="https://meetups.evrone.ru/go-meetup-online-2?utm_source=digest_site&amp;utm_medium=transition&amp;utm_campaign=go_digest_4_2023" rel=" noopener" target="_blank">Регистрация</a></p> <h2 id="article_title_8">Вакансии</h2> <p>Удаленка / Офис</p> <h3>Evrone </h3> <p>Мы открыты для новых Go-разработчиков. В Evrone можно работать удалённо с первого дня, мы поддерживаем и оплачиваем участие в Open-source проектах и выступления на конференциях, а расти в грейдах можно с помощью честной системы проверки навыков и менторства.</p> <p><a class="info-button" href="https://jobs.evrone.ru/?utm_source=digest_site&amp;utm_medium=digest&amp;utm_campaign=go_digest_4_2023" rel=" noopener" target="_blank">Подробнее</a></p> <p> </p> Tue, 18 Apr 2023 09:41:16 +0000 Evrone digest /20230418 От простого к сложному https://digest.evrone.ru/20230320 <img src="/sites/default/files/styles/card_m/public/2023-03/image1_2.png?itok=IUnr13lP" width="960" height="540" alt="От простого к сложному" loading="lazy" typeof="Image" /> <br /> <p>В мартовском Golang-дайджесте расскажем, как удобно демонстрировать результаты работы заказчикам, создавая туннели в публичный интернет. Также рассмотрим легковесную альтернативу веб-фреймворку makaron, почитаем стайлгайд от Uber и узнаем, как ускорить отдельно взятую функцию, переписав её на языке ассемблера.</p> <h2>Пробиваем туннели</h2> <p>Большую часть времени разработчики тратят не на написание кода, а на коммуникации. Им часто приходится демонстрировать свою работу заказчикам и это должно быть не просто скриншотами или видео. Клиенту хочется самостоятельно потыкать мышкой в результат, причем на своём компьютере. Значит надо придумать, как дать временный доступ.</p> <p>При разработке интеграции с внешними сервисами им тоже надо достучаться до рабочего компьютера, отправить или получить данные. Это сложно, поскольку в большинстве случаев разработчики выходят в сеть из-за NAT и не имеют статического IP-адреса. Это значит, что нужно сделать проброс портов (port forwarding) на маршрутизаторе, открыть порт файервола и стать клиентом сервиса, который будет актуализировать IP-адрес и привязывать к какому-либо домену (собственному или предоставляемому сервисом).</p> <p>Такой набор действий может не сработать. Если вы сидите через мобильный интернет, то у вас будет серый IP без возможности подключения извне. Ваш рабочий ноутбук вполне может иметь ограничение на управление файерволом, исходя из принятой в компании политики безопасности. Да и время обновления DNS-записей (штатно до 24 часов) может стать проблемой, если надо «здесь и сейчас».</p> <p>Одним из способов решения может быть аренда VDS со статическим IP, но это не всегда удобно. Получается, что либо разработку надо вести сразу там, либо тратить время на перемещение и запуск проекта на удалённом сервере. Куда проще воспользоваться сервисами, организующими туннель до вашего рабочего компьютера. Один из таких сервисов <a href="https://ngrok.com/" rel=" noopener" target="_blank">ngrok</a>, реализует модель ingress-as-a-service. Минимальная команда для работы выглядит так:</p> ngrok http 80 <p>Сервис выделит временный поддомен, который будет резолвиться сразу же, выполнит все необходимые действия по созданию туннеля через собственный промежуточный сервер. Таким образом мы избавляемся от всех проблем, связанных с пробросом портов, файерволами и NAT. Бонусом станет контроль трафика и его просмотр без отдельной настройки сниффера. Дополнительные плюшки в виде SSO, OAuth и SSL/TLS-сертификатов присутствуют.</p> <p>Единственный недостаток — <a href="https://ngrok.com/pricing" rel=" noopener" target="_blank">цена</a>. Для некоммерческих проектов сервис предоставляется бесплатно и с ограниченным функционалом. Независимым коммерческим разработчикам или командам придётся разово выложить от $8 до $65 за лицензию плюс от $10 до $75 ежемесячно за обслуживание.</p> <p>Если же у вас есть арендованный сервер и вы хотите получить selfhosted ngrok, то можно обратить внимание на проект <a href="https://github.com/jerson/pgrok" rel=" noopener" target="_blank">pgrok</a>. Его ещё называли ngrok для бедных (poor man's ngrok). Автор создал бесплатный сервис ejemplo.me, которым, к сожалению, <a href="https://github.com/jerson/pgrok/issues/20" rel=" noopener" target="_blank">воспользовались</a> злоумышленники для распространения вредоносного ПО. Итог был предсказуем: домен заблокировали, а репозиторий теперь в архиве, в статусе read-only. Тем не менее, серверную часть pgrokd можно запустить на своём сервере и использовать клиент pgrok для доступа.</p> <p>Аналогичный подход можно использовать с помощью проекта <a href="https://github.com/fatedier/frp" rel=" noopener" target="_blank">frp</a> (сокращение от fast reverse proxy). Его преимущество в том, что он продолжает активно развиваться. Файерволы и NAT ему не помеха, дополнительные фичи, вроде аутентификации через OIDC-провайдера есть. Отдельно отметим хорошую <a href="https://github.com/fatedier/frp/blob/dev/README.md" rel=" noopener" target="_blank">документацию</a> с примерами конфигурации.</p> <h2>Модульный фреймворк Flamego</h2> <p>Ненадолго поставим в сторону бокалы с <a href="https://github.com/gin-gonic/gin" rel=" noopener" target="_blank">gin</a> и <a href="https://github.com/go-martini/martini" rel=" noopener" target="_blank">martini</a> и взглянем на альтернативные веб-фреймворки. Наше внимание привлек <a href="https://github.com/flamego/flamego" rel=" noopener" target="_blank">Flamego</a>, впитавший в себя идеи модульного фреймворка <a href="https://github.com/go-macaron/macaron" rel=" noopener" target="_blank">makaron</a>, но этот легче и проще. Разработчики пожертвовали расширяемостью и получили много полезных бонусов.</p> <p>Основное, чем может похвастаться Flamego — мощный синтаксис маршрутизации, опережающий всех конкурентов по экосистеме. Этот фреймворк не накладывает ограничений на внедрение промежуточного программного обеспечения и обеспечивает достаточно простую интеграцию с существующими Go-приложениями.</p> <p>Отдельно стоит упомянуть возможность внедрения зависимостей через сигнатуры функции. Это значит, что зависимости передаются в функцию через её параметры. Например, если функция требует доступ к базе данных, то объект этой базы может быть передан в качестве аргумента. Такой подход позволяет гибче управлять зависимостями и сделать веб-приложение модульным.</p> <p>Модульное приложение имеет ряд преимуществ. Его легче тестировать, поскольку тестирование каждого модуля можно сделать независимо от других. На практике это означает более быструю локализацию проблем и их решение. Ну а добавить или удалить новые фичи можно без необходимости глобальных изменений всего приложения.</p> <p>Есть у Flamego и очевидные недостатки. Этот веб-фреймворк использует собственный формат middleware, что делает невозможным многие полезные вещи. В частности, нельзя использовать официальные прослойки от Prometeus / Grafana или любого стандартного роутера, такого как chi. Ещё один минус — активное использование reflect не лучший выбор с точки зрения производительности.</p> <h2>Uber Go стайлгайд</h2> <p>В нашем мартовском <a href="https://digest.evrone.ru/20230309" rel=" noopener" target="_blank">Python-дайджесте</a> мы рассказывали, что крупные компании вроде Google всё активнее делятся с сообществом собственными наработками. В частности, своими best practices, основанными на опыте использования разных языков программирования. Это позволяет значительно экономить средства на переделывание кода, написанного независимыми программистами для OSS-сообщества.</p> <p>Советуем обратить внимание на <a href="https://github.com/uber-go/guide/blob/master/style.md" rel=" noopener" target="_blank">руководство</a>, созданное двумя Go-разработчиками из Uber. Они хотели улучшить продуктивность коллег при работе с Golang. Этот документ неоднократно дополнялся и теперь содержит множество советов и рекомендаций. Каждый пункт основан на опыте решения проблем экспертами, имеющими многолетний опыт работы с Go.</p> <p>В документе можно найти подтверждение, что бытовые убеждения часто оказываются ложными. Когда вы пишете приложение, даже такая банальная вещь, как подсчёт времени может быть неожиданной. Если вы уверены, что в часе 60 минут, в сутках 24 часа, в неделе 7 дней, а в году их 365, то удивитесь. Все эти убеждения <a href="https://infiniteundo.com/post/25326999628/falsehoods-programmers-believe-about-time" rel=" noopener" target="_blank">ошибочны</a>, так что не стоит пренебрегать пакетом <a href="https://golang.org/pkg/time/" rel=" noopener" target="_blank">time</a>.</p> <p>Авторы выработали аргументированное мнение, что штатные механизмы паники и восстановления не являются верной стратегией обработки ошибок. С их точки зрения, любой код в продакшене должен избегать паники, поскольку та может быть источником каскадных отказов. Если возникла ошибка, то её надо вернуть и дать таким образом с ней справиться. Паника — признак непоправимой ситуации. Это справедливо всегда, за исключением паники во время инициализации приложения.</p> <p>Это лишь малая часть того, что детально разобрано в руководстве. Примеры очень наглядные и хорошо проиллюстрированные. Даже если не использовать все приведённые советы, то часть точно стоит взять за основу собственного руководства по стилю.</p> <h2>Экстремальное ускорение</h2> <p>Большинство приложений в нашем веке разрабатывается на высокоуровневых языках. Повсеместная виртуализация и контейнеризация отучили программистов думать, на каком железе будет работать их код. Это позволило существенно снизить порог входа и не особо задумываться, что происходит на уровне ниже.</p> <p>Но если нам надо ускорить какую-то одну определённую функцию, чтобы та работала существенно быстрее? Тут на ум приходит воспользоваться языком ассемблера и попробовать говорить с процессором на его языке. Один из пользователей Хабра <a href="https://habr.com/ru/post/720582/" rel=" noopener" target="_blank">проделал</a> такой трюк и описал свой опыт.</p> <p>Здесь стоит начать с дисклеймера — это вряд ли пригодится в реальной разработке. Ни о какой надёжности речи не идёт. Рассматривайте это, как любопытный эксперимент, не более. (прим. автора)</p> <p>В качестве подопытного кролика была выбрана модифицированная функция Copy для решения задачи по спортивному программированию:</p> func Copy(srcRGBA, dstPaletted []uint8) { srcPtr := unsafe.Add(unsafe.Pointer(&amp;srcRGBA[0]), 2) dstPtr := unsafe.Pointer(&amp;dstPaletted[0]) for range dstPaletted { *(*uint8)(dstPtr) = *(*uint8)(srcPtr) dstPtr = unsafe.Add(dstPtr, 1) srcPtr = unsafe.Add(srcPtr, 4) } } <p>У Go есть полезный флаг компиляции -gcflags "-S", выводящий программу в виде кода на языке ассемблера. Чтобы упростить вывод, автор статьи задействовал флаг -B, отключающий проверку границ (Bounds Check). Вот та же самая функция Copy:</p> 0x0000 00000 TEXT round-3/fastcopy.Copy(SB), NOSPLIT|ABIInternal, $0-48 0x0000 00000 MOVQ AX, round-3/fastcopy.srcRGBA+8(FP) 0x0005 00005 MOVQ DI, round-3/fastcopy.dstPaletted+32(FP) 0x000a 00010 FUNCDATA $0, gclocals·cNGUyZq94N9QFR70tEjj5A==(SB) 0x000a 00010 FUNCDATA $1, gclocals·J5F+7Qw7O7ve2QcWC7DpeQ==(SB) 0x000a 00010 FUNCDATA $5, round-3/fastcopy.Copy.arginfo1(SB) 0x000a 00010 FUNCDATA $6, round-3/fastcopy.Copy.argliveinfo(SB) 0x000a 00010 PCDATA $3, $1 0x000a 00010 ADDQ $2, AX 0x000e 00014 XORL CX, CX 0x0010 00016 JMP 33 0x0012 00018 MOVBLZX (AX), DX 0x0015 00021 MOVB DL, (DI) 0x0017 00023 INCQ CX 0x001a 00026 INCQ DI 0x001d 00029 ADDQ $4, AX 0x0021 00033 CMPQ SI, CX 0x0024 00036 JGT 18 0x0026 00038 RET <p>Было выбрано несколько направлений оптимизации.</p> <ol> <li aria-level="1">Уменьшить количество чтений из памяти.</li> <li aria-level="1">Уменьшить количество записей в память.</li> <li aria-level="1">Выполнять операции с большим количеством данных за счёт AVX-инструкций.</li> </ol> <p>Первое направление было выполнено чтением сразу 8 байт за раз, в то время как в оригинальном коде читался только 1 байт в регистр размером 8 байт. Полученный код был оптимизирован за счёт <a href="https://habr.com/ru/post/124910/" rel=" noopener" target="_blank">развёртки цикла</a>, выполнения XORQ на первом шаге цикла и сборке 8 байт в регистр перед записью. Ну а вишенкой на торте стало задействование векторных инструкций. Суммарно все эти оптимизации смогли ускорить функцию почти в 10 раз.</p> <p>Само же встраивание ассемблерной функции в Go-приложение выполняется элементарно. В код добавляется функция без тела, вида:</p> func CopyAsm(srcRGBA, dstPaletted []uint8) <p>Реализация на языке ассемблера кладётся в файл с расширением .s. При этом нужно использовать суффикс, обозначающий конкретную архитектуру, например, fastcopy_amd64.s. Вот такой любопытный способ для экстремального ускорения одной конкретно взятой функции.</p> <h2 id="article_title_4">Видеоподкаст про Go</h2> <p><a href="https://www.youtube.com/channel/UCzjQIaveGe_G8yT9iFcKwTQ/featured" rel=" noopener" target="_blank">Подкаст</a> снимают и развивают двое наших коллег из Evrone. Они обсуждают его преимущества и недостатки, сравнивают с другими языками. </p><p>Выпуски длятся 50-70 минут, а значит можно совместить какие-нибудь скучные занятия с обучением. Отличная возможность погрузится в нюансы Go, стоя в пробке или проезжая очередную станцию метро!</p> <p>Ну а если вам есть что сказать — добро пожаловать в комментарии!</p> <h2 id="article_title_7">Митапы</h2> Онлайн <h3>Go meetup</h3> <p>26 апреля 2023</p> <p>Уже совсем скоро мы встретимся на Go Meetup. Программа мероприятия формируется, но регистрация уже открыта. Кстати, вы уже можете <a href="https://forms.gle/svgvCCxM7cRTL3wX7" rel=" noopener" target="_blank">подать доклад</a> прямо в режиме онлайн.</p> <p>Интересуетесь нашими мероприятиями? В Telegram-канале <a href="https://t.me/meetups_evrone" rel=" noopener" target="_blank">Evrone meetups</a> мы выкладываем анонсы с подробными описаниями докладов, а также студийные записи прошедших митапов. Тем для кого выступать в новинку, мы оказываем всяческую поддержку и помогаем оформить экспертизу в яркое выступление. Подписывайтесь и пишите <a href="https://t.me/andrew_aquariuss" rel=" noopener" target="_blank">@andrew_aquariuss</a>, чтобы узнать подробности.</p> <p><a class="info-button" href="https://meetups.evrone.ru/go-meetup-online-2?utm_source=digest_site&amp;utm_medium=transition&amp;utm_campaign=go_digest_3_2023" rel=" noopener" target="_blank">Регистрация</a></p> <h2 id="article_title_8">Вакансии</h2> <p>Удаленка / Офис</p> <h3>Evrone </h3> <p>Мы открыты для новых Go-разработчиков. В Evrone можно работать удалённо с первого дня, мы поддерживаем и оплачиваем участие в Open-source проектах и выступления на конференциях, а расти в грейдах можно с помощью честной системы проверки навыков и менторства.</p> <p><a class="info-button" href="https://jobs.evrone.ru/?utm_source=digest_site&amp;utm_medium=transition&amp;utm_campaign=go_digest_3_2023" rel=" noopener" target="_blank">Подробнее</a></p> Mon, 20 Mar 2023 14:10:10 +0000 Evrone digest /20230320 Обновление языка и телеметрия https://digest.evrone.ru/20230214 <img src="/sites/default/files/styles/card_m/public/2023-02/image1_1.png?itok=sTDA6Yil" width="960" height="540" alt="Обновление языка и телеметрия" loading="lazy" typeof="Image" /> <br /> <p>Язык Go развивается, каждый новый релиз делает его лучше. Сегодня расскажем о важных изменениях, узнаем идею нового дизайна телеметрии для проектов с открытым исходным кодом и попробуем интегрировать данные из Go-приложения в HTML-шаблон.</p> <h2>Hurrah, Go 1.20 is released!</h2> <p><a href="https://go.dev/dl/" rel=" noopener" target="_blank">Версия 1.20</a>, вышедшая 1 февраля 2023 года, принесла 4 ключевых изменения. Она расширила возможности конвертации из слайса в указатель массива. Так что, имея слайс x, конструкцию *(*[4]byte)(x) теперь можно записать значительно проще — [4]byte(x).</p> <p>Встроенный в язык пакет <a href="https://pkg.go.dev/unsafe" rel=" noopener" target="_blank">unsafe</a>, позволяющий выполнять низкоуровневые операции с памятью, пополнился тремя новыми функциями:</p> <ul> <li aria-level="1">SliceData,</li> <li aria-level="1">String,</li> <li aria-level="1">StringData.</li> </ul> <p>С помощью них можно конструировать и деконструировать слайсы и строковые значения без зависимости от их точного представления. При этом не стоит забывать об осторожности, ведь unsafe позволяет действовать почти без оглядки на ограничения языка. Всегда проверяйте код, чтобы не выстрелить себе в ногу.</p> <p>Спецификация также подверглась некоторым изменениям. Раньше можно было неправильно понять, как сравниваются значения структур. Теперь там явно указано, что эти значения сравниваются по одному полю за раз. Порядок при этом соблюдается тот, в котором поля появлялись в определении типа структуры. Процесс останавливается при первом же найденном несоответствии.</p> <p>Не забыли разработчики языка и об улучшении процесса сравнения. До выхода 1.20 правила сравнения были достаточно жёсткими. Они требовали явного соответствия по типу для корректной работы. Возьмём пример кода:</p> package main import "fmt" type mymap[K comparable, V any] map[K]V func _[P any, Q comparable]() { var _ mymap[any, string] // не сработает в старых версиях до 1.20 } func main() { fmt.Println("Hello, gophers!") } <p>Если запустить его, например, в версии 1.19, то получим ошибку вида:</p> ./prog.go:8:14: any does not implement comparable Go build failed. <p>А вот в новой версии 1.20 функция отработает без каких-либо проблем. </p> <p>Смягчение правил даст возможность меньше думать про различия и задействовать данные, которые используют разные интерфейсы. Обратная сторона медали — в рантайме может оказаться, что какие-то типы сравнивать нельзя.</p> <h2>Дизайн прозрачной телеметрии</h2> <p>Практически любой разработчик знает этот замечательный момент. Работа над релизом завершена, софт отправился пользователям. Но как узнать, что всё работает как надо? Как понять, что не возникает каких-либо нежелательных эффектов? В этом случае простых отчётов об ошибках и пользовательских отзывов будет недостаточно. </p> <p>Даже незначительная разница между пользовательским устройством и средой, в которой разработчики выполняли тестирование, может стать причиной, по которой баг не был вовремя обнаружен. При масштабировании различия будут лишь увеличиваться. Без сбора и анализа телеметрии некоторые проблемы приложений выявить практически нереально.</p> <p>Выбор телеметрии может быть сложным. Проекты с открытым исходным кодом предпочитают не собирать следы активности. Это помогает избежать необоснованных обвинений в сборе пользовательских данных. К тому же, собранные данные должны быть обезличены и их нужно где-то хранить. </p> <p>Конечно, можно предпочесть стратегию «do nothing», но это лишь приведёт к существенному недостатку знаний. Как результат — ошибочные решения, которые никак не соотносятся с реальными потребностями пользователей.</p> <p>Но есть и примеры успешного внедрения традиционной телеметрии. Звуковой редактор <a href="https://www.audacityteam.org/" rel=" noopener" target="_blank">Audacity</a>, платформа <a href="https://about.gitlab.com/" rel=" noopener" target="_blank">GitLab</a> и пакетный менеджер <a href="https://github.com/Homebrew" rel=" noopener" target="_blank">Homebrew</a> для macOS не скрывают, что собирают телеметрию. Те, кто работает в Visual Studio Code также не слишком сильно переживают по этому поводу, если верить <a href="https://survey.stackoverflow.co/2022/#integrated-development-environment" rel=" noopener" target="_blank">опросу</a> 2022 года от StackOverflow. Возможно, это сыграло свою роль и сделало VSCode лучше.</p> <p><a href="https://swtch.com/~rsc/" rel=" noopener" target="_blank">Расс Кокс</a> (Russ Cox) за свою 16-летнюю карьеру в Google сделал вывод, что телеметрия особенно важна для проектов с открытым исходным кодом. Это позволяет избежать ситуаций, при которых разработчик не знает, как используется его софт и насколько хорошо он работает. В то же время те, кто разрабатывает проприетарное программное обеспечение используют сбор телеметрии на полную катушку.</p> <p>Если хирургу необходимо сделать операцию, то он старается минимизировать инвазивное вмешательство. Особенность нового <a href="https://research.swtch.com/telemetry-intro#summary" rel=" noopener" target="_blank">дизайна прозрачной телеметрии</a>, предложенной Рассом, базируется на том, чтобы собирать как можно меньше обезличенных данных. Если в цифрах, то это может быть 1 Кбайт в год с каждой установки. Полученные данные затем стоит делать доступными для публичного просмотра и анализа. Пока что всё это в процессе <a href="https://github.com/golang/go/discussions/58409" rel=" noopener" target="_blank">обсуждения</a> с сообществом, но уже есть некоторые важные особенности.</p> <p>Никаких псевдослучайных идентификаторов, IP-адресов или MAC-адресов. Разработчик может составить список значимых для него событий, а приложение будет вести учёт количества таких событий. В процессе отправки данных отчёт может включать интересующие значения счётчиков, версию ОС и архитектуру. Опционально могут быть добавлены данные о других инструментах, например версии локального компилятора.</p> <h2>Плюшевый гофер</h2> <p>Если вы хоть раз имели дело с Ruby, то знаете, что существует такой язык разметки, как eRuby. Эталонная реализация этого языка называется ERB и включена в стандартную библиотеку. С помощью ERB появляется возможность встраивать код на Ruby непосредственно в HTML-документ. Чтобы определить границы встраивания используются пары разделителей &lt;% и %&gt;. Таким образом, можно вычислять и подставлять значения сразу в HTML-шаблон. Можно ли провернуть такой трюк в Golang?</p> <p>Посмотрите на механизм шаблонов <a href="https://github.com/gobuffalo/plush" rel=" noopener" target="_blank">Plush</a>, входящий в состав фреймворка <a href="https://github.com/gobuffalo" rel=" noopener" target="_blank">Buffalo</a>. Его можно использовать в Go-приложениях отдельно от экосистемы Buffalo. Устанавливается Plush одной командой:</p> $ go get -u github.com/gobuffalo/plush <p>Синтаксис здесь очень похож на ERB. В частности, для динамического отображения содержимого используются разделители &lt;%= и %&gt;.</p> &lt;!-- input --&gt; &lt;p&gt;&lt;%= "plush is great" %&gt;&lt;/p&gt; &lt;!-- output --&gt; &lt;p&gt;plush is great&lt;/p&gt; <p>Чтобы исполнить код, но не отображать его в шаблоне можно видоизменить разделители до &lt;% и %&gt;. </p> &lt;!-- input --&gt; &lt;p&gt;&lt;% "plush is great" %&gt;&lt;/p&gt; &lt;!-- output --&gt; &lt;p&gt;&lt;/p&gt; <p>С помощью этих же тегов создаются переменные и функции внутри шаблонов для последующего использования. Вместе с этим можно добавлять комментарии, выстраивать циклы и многое другое. В итоге получаем отличную возможность рендеринга web-страниц с данными из Go-приложений.</p> <h2 id="article_title_4">Видеоподкаст про Go</h2> <p><a href="https://www.youtube.com/channel/UCzjQIaveGe_G8yT9iFcKwTQ/featured" rel=" noopener" target="_blank">Подкаст</a> снимают и развивают двое наших коллег из Evrone. Они обсуждают его преимущества и недостатки, сравнивают с другими языками.</p> <p>Выпуски длятся 50-70 минут, а значит можно совместить какие-нибудь скучные занятия с обучением. Отличная возможность погрузится в нюансы Go, стоя в пробке или проезжая очередную станцию метро!</p> <p>Ну а если вам есть что сказать — добро пожаловать в комментарии!</p> <h2 id="article_title_7">Митапы</h2> Онлайн <h3>Go meetup</h3> <p>15 марта 2023</p> <p>Уже совсем скоро мы встретимся на Go Meetup. Программа мероприятия формируется, но регистрация уже открыта. Кстати, вы уже можете <a href="https://forms.gle/svgvCCxM7cRTL3wX7" rel=" noopener" target="_blank">подать доклад</a> прямо в режиме онлайн. Заявки на участие принимаются до 1 марта.</p> <p>Интересуетесь нашими мероприятиями? В Telegram-канале <a href="https://t.me/meetups_evrone">Evrone meetups</a> мы выкладываем анонсы с подробными описаниями докладов, а также студийные записи прошедших митапов. Тем для кого выступать в новинку, мы оказываем всяческую поддержку и помогаем оформить экспертизу в яркое выступление. Подписывайтесь и пишите <a href="https://t.me/andrew_aquariuss">@andrew_aquariuss</a>, чтобы узнать подробности.</p> <p><a class="info-button" href="https://meetups.evrone.ru/go-meetup-online-2?utm_source=digest_site&amp;utm_medium=transition&amp;utm_campaign=go_digest_2_2023" rel=" noopener" target="_blank">Регистрация</a></p> <h2 id="article_title_8">Вакансии</h2> <p>Удаленка / Офис</p> <h3>Evrone </h3> <p>Мы открыты для новых Go-разработчиков. В Evrone можно работать удалённо с первого дня, мы поддерживаем и оплачиваем участие в Open-source проектах и выступления на конференциях, а расти в грейдах можно с помощью честной системы проверки навыков и менторства.</p> <p><a class="info-button" href="https://jobs.evrone.ru/?utm_source=digest_site&amp;utm_medium=transition&amp;utm_campaign=go_digest_2_2023" rel=" noopener" target="_blank">Подробнее</a></p> Tue, 14 Feb 2023 13:02:01 +0000 Evrone digest /20230214 Архитектура и управление https://digest.evrone.ru/20230118 <img src="/sites/default/files/styles/card_m/public/2023-01/go%201.png?itok=AXSBEVcX" width="960" height="540" alt="Архитектура и управление" loading="lazy" typeof="Image" /> <br /> <p>С наступившим, гоферы! Поговорим про чистую архитектуру и хороший код, взглянем на экспериментальную фичу по управлению памятью и узнаем про альтернативу традиционному OpenSSH-серверу.</p> <h2>Чистая архитектура</h2> <p>Умение адаптироваться к внешним условиям — важное условие разработки для бизнеса. Как только бизнес требует внести изменение, а разработчик начинает сомневаться, не сломает ли это какую-то функциональность — это хороший повод задуматься о переходе на чистую архитектуру. Это даст возможность организовать код так, чтобы не зависеть от используемых фреймворков, UI или баз данных. Бонусом станет предсказуемое поведение всех компонентов построенной системы.</p> <p>Минусов у чистой архитектуры тоже достаточно. Необходимо соблюдать правила обмена данными между условными «слоями» приложения. Так что решение даже простых задач потребует написания большего количества кода. Проектировать взаимодействие модулей сложно. Это дополнительный барьер для внедрения чистой архитектуры.</p> <p>Удобно иметь наглядный пример такой архитектуры, вроде проекта <a href="https://github.com/amitshekhariitbhu/go-backend-clean-architecture" rel=" noopener" target="_blank">go-backend-clean-architecture</a>. Это такой шаблон с заранее подобранными слоями и проверенными временем инструментами. Общая схема взаимодействия выглядит следующим образом:</p> <p><img alt="Чистая архитектура" data-entity-type="file" data-entity-uuid="86866e6b-f567-4c85-91b8-8b972abbc344" width="1280" height="720" loading="lazy" class="lazyload" data-src="/sites/default/files/inline-images/image3_2.png" /></p> <p>В качестве инструментов для реализации этой схемы автор выбрал достаточно популярные пакеты:</p> <ul> <li aria-level="1"><a href="https://pkg.go.dev/github.com/gin-gonic/gin" rel=" noopener" target="_blank">gin</a> — веб-фреймворк;</li> <li aria-level="1"><a href="https://github.com/mongodb/mongo-go-driver" rel=" noopener" target="_blank">mongo go driver</a> — коннектор для MongoDB;</li> <li aria-level="1"><a href="https://pkg.go.dev/github.com/golang-jwt/jwt" rel=" noopener" target="_blank">jwt</a> — аутентификация на основе токенов;</li> <li aria-level="1"><a href="https://pkg.go.dev/github.com/dvln/viper" rel=" noopener" target="_blank">viper</a> — загрузчик конфигурации;</li> <li aria-level="1"><a href="https://pkg.go.dev/golang.org/x/crypto/bcrypt" rel=" noopener" target="_blank">bcrypt</a> — хэш-функция формирования ключа;</li> <li aria-level="1"><a href="https://github.com/stretchr/testify" rel=" noopener" target="_blank">testify</a> — тестирование правильности работы кода;</li> <li aria-level="1"><a href="https://github.com/vektra/mockery" rel=" noopener" target="_blank">mockery</a> — фиктивная реализация интерфейсов.</li> </ul> <p>Существует два варианта развёртывания шаблона: в Docker-контейнере и локально (требуется наличие установленного go и MongoDB). Документация для каждого из вариантов есть в репозитории проекта. </p> <p>Если вы серьёзно задумались, как спроектировать приложение на чистой архитектуре, обратите внимание на книгу «Чистая архитектура. Искусство разработки программного обеспечения» Роберта Мартина. В ней освещены вопросы архитектуры и дизайна приложений. Это универсальные знания, которые будут полезны разработчикам, системным архитекторам и аналитикам данных.</p> <h2>Экспериментальная arena</h2> <p>Остаётся совсем немного времени до февральского релиза Go 1.20. Есть в нём одна интересная экспериментальная фича — <a href="https://github.com/golang/go/issues/51317" rel=" noopener" target="_blank">арены памяти</a>. Давайте кратко разберёмся, что это такое и зачем нужно.</p> <p>Не секрет, что в Golang существует специфический garbage collector (GC). Именно он следит, чтобы приложение не упало, обожравшись памяти. Задумка была такая, чтобы разработчику в целом не приходилось заботиться о ручном управлении памятью.</p> <p>Пока приложение выполняется, GC следит за объектами и помечает трёхцветным алгоритмом, какие из них оставить в куче, а какие удалить. Как только размер помеченных на удаление объектов удваивает изначальный размер кучи — именно в этот момент происходит стирание объектов и освобождение памяти.</p> <p>Есть в этой схеме несколько недостатков. Проблема в том, что часто возникают ситуации, при которых GC мог бы работать быстрее. Вот только у разработчиков нет возможности ручного контроля поведения GC. Есть лишь возможность задать, при каком соотношении размера кучи к помеченным на удаление объектам будет запускаться очистка.</p> <p>Вот тут мы возвращаемся к тому, с чего начали — аренам памяти. Это попытка <a href="https://uptrace.dev/blog/posts/go-memory-arena.html" rel=" noopener" target="_blank">увеличить производительность</a> за счёт того, что в специально выделенных участках памяти (аренах) GC не будет функционировать. При этом у разработчика будет возможность выделять адреса объектов в такой арене, а также иметь возможность вручную запустить процесс освобождения памяти через вызов free. При этом вся арена будет очищена.</p> <p>Таким образом, вдобавок к стандартному GC, которым нельзя управлять вручную, появляется выделенная область, где обычные правила не действуют. Это даёт больше контроля, но и порождает целый пласт вопросов и проблем. Самый популярный вопрос — а в каких сценариях реально будет необходимость задействовать такой механизм?</p> <p>Предположим, у вас есть некая структура связанных данных, например, B-дерево. Скорее всего, она будет долгоживущей и практически неизменной. В этом случае нет смысла тратить на неё время GC, проще будет её стереть целиком. Это одно из потенциальных применений арены памяти — хранить подобные структуры данных.</p> <p>Ну а проблемами здесь могут стать контроль за утечкой памяти и попытка чтения/записи в структуру на освобождённой арене. Предполагается, что в первом случае будут хорошо работать штатные механизмы профилирования. А для второго Address sanitizer и Memory sanitizer через go run -asan и go run -msan соответственно.</p> <h2>Альтернатива OpenSSH</h2> <p>В большинстве случаев мануалы по SSH пишутся с точки зрения пользователя или системного администратора. Если надо реализовать что-либо с помощью этого протокола, то обычно разработчики имеют дело с <a href="https://www.openssh.com/" rel=" noopener" target="_blank">OpenSSH</a>. Это в большинстве случаев работает хорошо, но не всегда.</p> <p>Когда нужно плотно работать с TUI или обеспечить дополнительную безопасность, разумным решением будет обратиться к альтернативным платформам. Одна из таких платформ, <a href="https://github.com/charmbracelet/wish" rel=" noopener" target="_blank">Wish</a>. Вот демонстрация работы:<br /> <br /> <img alt="Wish" data-entity-type="file" data-entity-uuid="512bd8ac-2c26-4fe4-ad84-256802144896" width="816" height="492" loading="lazy" class="lazyload" data-src="/sites/default/files/inline-images/image2_1.gif" /></p> <p> </p> <p>Впрочем, можете самостоятельно подключиться к SSH-серверу git.charm.sh и проверить работу платформы. Используя связку из небольшого TUI-фреймворка <a href="https://github.com/charmbracelet/bubbletea" rel=" noopener" target="_blank">BubbleTea</a> и Wish, можно создавать красивые приложения, предназначенные для работы в терминальном режиме.</p> <p>Автор платформы не стал изобретать велосипед и воспользовался готовой реализацией протокола от <a href="https://github.com/gliderlabs/ssh" rel=" noopener" target="_blank">GliderLabs</a>. Её писали в сотрудничестве с разработчиком знаменитого <a href="https://github.com/shazow/ssh-chat" rel=" noopener" target="_blank">ssh-chat</a>.</p> <h2>Видеоподкаст про Go</h2> <p>Видеоподкаст "Немного IT" снимают и развивают двое наших коллег из Evrone. Они обсуждают его преимущества и недостатки, сравнивают с другими языками. Выпуски длятся 50-70 минут, а значит можно совместить какие-нибудь скучные занятия с обучением. Отличная возможность погрузится в нюансы Go, стоя в пробке или проезжая очередную станцию метро! Ну а если вам есть что сказать — добро пожаловать в комментарии! <a href="https://someit.tech/" rel=" noopener" target="_blank">Сайт</a> проекта.</p> <h2 id="article_title_7">Митапы</h2> Онлайн <h3>Go meetup</h3> <p>15 марта 2023</p> <p>Год только начался, а у нас уже запланирован Go Meetup, который пройдёт 15 марта 2023. Программа мероприятия формируется, но регистрация уже открыта. Кстати, вы уже <a href="https://forms.gle/svgvCCxM7cRTL3wX7" rel=" noopener" target="_blank">можете подать доклад</a> прямо в режиме онлайн. Заявки на участие принимаются до 1 марта.</p> <p>Интересуетесь нашими мероприятиями? В Telegram-канале <a href="https://t.me/meetups_evrone">Evrone meetups</a> мы выкладываем анонсы с подробными описаниями докладов, а также студийные записи прошедших митапов. Тем для кого выступать в новинку, мы оказываем всяческую поддержку и помогаем оформить экспертизу в яркое выступление. Подписывайтесь и пишите <a href="https://t.me/andrew_aquariuss">@andrew_aquariuss</a>, чтобы узнать подробности.</p> <p><a class="info-button" href="https://meetups.evrone.ru/go-meetup-online-2?utm_source=digest_site&amp;utm_medium=transition&amp;utm_campaign=go_digest_1_2023" rel=" noopener" target="_blank">Регистрация</a></p> <h2 id="article_title_8">Вакансии</h2> <p>Удаленка / Офис</p> <h3>Evrone </h3> <p>Мы открыты для новых Go-разработчиков. В Evrone можно работать удалённо с первого дня, мы поддерживаем и оплачиваем участие в Open-source проектах и выступления на конференциях, а расти в грейдах можно с помощью честной системы проверки навыков и менторства.</p> <p><a class="info-button" href="https://jobs.evrone.ru/?utm_source=digest_site&amp;utm_medium=transition&amp;utm_campaign=go_digest_1_2023" rel=" noopener" target="_blank">Подробнее</a></p> Wed, 18 Jan 2023 13:07:00 +0000 Evrone digest /20230118 13 лет совершенствования https://digest.evrone.ru/20221118 <img src="/sites/default/files/styles/card_m/public/2022-11/go_11.png?itok=Xc0Fyjb1" width="960" height="540" alt="13 лет совершенствования" loading="lazy" typeof="Image" /> <br /> <p>В ноябре мы празднуем очередной день рождения языка, радуемся пополнению CNCF-песочницы инструментом для создания Go-контейнеров, смотрим на практическое применение фаззинга и размышляем об IDE будущего. Не переключайтесь!</p> <h2>Гофер-тинейджер</h2> <p>Наш гофер <a href="https://go.dev/blog/13years" rel=" noopener" target="_blank">отпраздновал</a> в ноябре своё 13-летие. По человеческим меркам это уже подросток, отказавшийся от прошлых убеждений и активно ищущий возможности развития. Релиз 1.18 поставил жирную точку в спорах про дженерики, и это стало определяющим моментом выбора пути дальнейшего совершенствования. Остальные, не менее важные изменения, такие как рабочие области и фаззинг, можно считать приятным бонусом.</p> <p>Понемногу в язык приходит удобство не только для написания кода, но и для документирования. В комментариях теперь есть базовые структурные элементы, помогающие улучшать восприятие — заголовки, списки и ссылки. Приложения всё чаще запускают в контейнерах, что привело к появлению вспомогательных механизмов, таких как мягкое ограничение памяти GC.</p> <p>Стоит оглянуться на уже пройденный путь и увидеть, через что прошел язык за все эти годы. Идея отодвинуть C на второй план более не является драйвером развития. Причём путь Go — не только история успеха, но и провалов. Недавний эпизод с уязвимостью Log4shell заставил пересмотреть отношение к безопасности и привёл к созданию инструментов вроде <a href="https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck" rel=" noopener" target="_blank">govulncheck</a>.</p> <p>Впереди будет ещё множество «‎синяков» и «‎набитых шишек», но мы в Evrone склонны верить, что этап детства позади, а Go ждёт отличное будущее. Нам же остаётся продолжать наращивать свою экспертизу и делиться опытом с «‎коллегами по цеху».</p> <h2>Easy Go Containers</h2> <p>Песочница CNCF пополнилась ещё одним полезным инструментом, а именно <a href="https://github.com/ko-build/ko" rel=" noopener" target="_blank">проектом ko</a>. История его создания началась в 2018 году в процессе разработки решения <a href="https://knative.dev/" rel=" noopener" target="_blank">Knative</a>. Нужно было создать удобный инструмент развёртывания Go-приложений в контейнеры Kubernetes. Разработчики блестяще справились с этой задачей и их детище теперь стало очередным вкладом в развитие open-source software.</p> <p>Основным юзкейсом ko является упаковка Go-приложения в образ и его отправка в реестр для контейнеров (например, в Container Registry) без необходимости создания Dockerfile. Любопытно, что на хосте вообще может не быть установлен Docker. За основу ko берёт образ <a href="https://github.com/GoogleContainerTools/distroless" rel=" noopener" target="_blank">distroless</a> вообще без оболочки и исполняемых файлов. Это делает его безопаснее и меньше по размеру.</p> <p>В целом, ko можно рассматривать как простой и функциональный конструктор, экономящий время. Если локальный билдер Docker формирует образы через запуск контейнера и снятие снапшотов с файловой системы, то ko действует иначе. Он напрямую формирует образ и манифест вообще без запуска контейнера. Это и приводит к экономии времени.</p> <h2>Вновь о фаззинге</h2> <p>Наверняка у вас были такие ситуации, когда звучала фраза «‎я бы в жизни не догадался». И это именно та фраза, которая объясняет, что делает фаззинг. Он позволяет выявить такие баги, о которых невозможно догадаться. Как в знаменитой фразе из фильма ДМБ — «‎Суслика видишь? Вот и я не вижу. А он есть».</p> <p>Это достаточно старый метод тестирования, появившийся случайно. Во время передачи данных с терминала на мейнфрейм случился сбой, и до мейнфрейма долетела команда с аргументами в виде случайного набора символов. Это, в свою очередь, вызвало segmentation fault и падение команды, которая до этого многократно тестировалась.</p> <p>Получилось, что сработал сценарий, который нельзя было предугадать. Это стало поворотным моментом, который привёл к созданию первых фаззеров, отправляющих сгенерированный «‎мусор» на ввод Unix-систем. Но если с привычными командами всё достаточно просто, то где в коде следует искать баги таким способом?</p> <p>Чтобы ответить на этот вопрос, важно понимать, что фаззинг не заменяет традиционные методы тестирования, но отлично их дополняет. Даже самые привычные функции, такие как сортировка слайса, в какой-то момент могут сработать не так, как предусматривает разработчик. И там, где модульные тесты не найдут каких-либо отклонений — фаззер способен удивить. Особенно это полезно при парсинге чего-либо из внешнего мира, когда мы можем лишь предполагать, какие данные поступят на вход приложения.</p> <p>Наиболее простой способ перейти от теории к практике — посмотреть, как это уже применяется в реальных кейсах. Мы подготовили небольшую подборку статей, которые стоит прочитать:</p> <ul> <li aria-level="1"><a href="https://habr.com/ru/company/kaspersky/blog/696724/" rel=" noopener" target="_blank">Где искать баги фаззингом и откуда вообще появился этот метод</a></li> <li aria-level="1"><a href="https://adalogics.com/blog/structure-aware-go-fuzzing-complex-types" rel=" noopener" target="_blank">Structure-aware Go fuzzing: How to fuzz with complex types</a></li> <li aria-level="1"><a href="https://betterprogramming.pub/fuzzing-in-go-40796a54dc8b" rel=" noopener" target="_blank">Understanding fuzzing in Go</a></li> </ul> <h2>The IDE Of The Future</h2> <img alt="Внешний вид Fleet" data-entity-type="file" data-entity-uuid="d9e36994-55d0-47c8-9ede-e3a3a07e5329" width="1114" height="621" loading="lazy" class="lazyload" data-src="/sites/default/files/inline-images/image2_2.png" /> Внешний вид Fleet <p><span>Разработчики много проводят времени в IDE — это факт. И вопрос удобства работы здесь вовсе не праздный. Среди гоферов наиболее часто используется Visual Studio Code от Microsoft и Goland от JetBrains. Последние, впрочем, не останавливаются на достигнутом и предлагают взглянуть на preview-версию их нового детища </span><a href="https://www.jetbrains.com/fleet/" rel=" noopener" target="_blank">Fleet</a><span>. Это интересная попытка заглянуть в будущее и создать универсальную IDE, в которой разработчикам будет удобно писать приложения на самых разных языках.</span></p> <p>Первое, что бросается в глаза: если код находится за пределами локальной машины, то можно получить к нему доступ разными способами. Можно сразу склонировать код из репозитория на GitHub, подключиться к удалённому серверу по SSH, получить доступ к Docker-контейнеру или нативной для JetBrains платформы Space.</p> <img alt="Окно поиска GOTO" data-entity-type="file" data-entity-uuid="3f07c049-f420-4c94-b694-6b794ed02aac" width="1114" height="621" loading="lazy" class="lazyload" data-src="/sites/default/files/inline-images/image3_1.png" /> Окно поиска GOTO <p>Интерфейс очень похож на VSCode и интуитивно понятен. Есть типичный для продуктов IntelliJ экран поиска GOTO, позволяющий найти нужный текст в кодовой базе, а затем сразу открыть файл и перейти к нужному месту. Словно хороший официант, Fleet сам предложит создать модульный тест при написании функции. В процессе отладки он отобразит все горутины, что достаточно удобно для определения состояния каждого из запущенных процессов.</p> <p>Это лишь малая часть интересных функций новой IDE. Более подробное описание вы найдёте в статье <a href="https://programmingpercy.tech/blog/previewing-the-ide-of-the-future" rel=" noopener" target="_blank">Previewing The IDE Of The Future</a> и <a href="https://blog.jetbrains.com/fleet/2022/10/introducing-the-fleet-public-preview/" rel=" noopener" target="_blank">блоге разработчиков</a>. Станет ли Fleet конкурентом VSCode? Посмотрим. Все задатки у него есть.</p> <h2>Интересно посмотреть</h2> <h3>Go-митап</h3> <p>Пропустили наш предыдущий Go-митап? Не страшно — записи докладов в кинематографическом качестве выложены в сеть. </p> <p>Антон Губарев из Авито рассказал про опыт реализации ролевой системы доступа с помощью Open Policy Agent:</p> <p>Николай Тузов из Lamoda детально описал внутреннее устройство каналов в Go:</p> <p>В завершение Андрей Беренда из Ozon Fintech поделился опытом взаимодействия с ошибками, которые нельзя обработать в Golang:</p> <h3> </h3> <h3>Немного IT</h3> <p><a href="https://www.youtube.com/channel/UCzjQIaveGe_G8yT9iFcKwTQ/featured" rel=" noopener" target="_blank">Видеоподкаст про Go</a> снимают и развивают двое наших коллег из Evrone. Они обсуждают его преимущества и недостатки, сравнивают с другими языками. </p> <p>Выпуски длятся 50-70 минут, а значит можно совместить какие-нибудь скучные занятия с обучением. Отличная возможность погрузится в нюансы Go, стоя в пробке или проезжая очередную станцию метро! <a href="https://someit.tech/" rel=" noopener" target="_blank">Сайт проекта</a>.</p> <p>Ну а если вам есть что сказать — добро пожаловать в комментарии!</p> <p>Впереди Рождество и Новый год — время, когда каждый хочет уделить время родным и близким. Поэтому это завершающий Go-дайджест 2022 года, а следующий выйдет в январе 2023, где мы соберём самые интересные новости, дискуссии и инструменты за 2 месяца сразу. Спасибо, что читаете нас!</p> <h2 id="article_title_8">Вакансии</h2> <span>Удаленка / Офис</span> <h3>Evrone </h3> <p>Мы открыты для новых Go-разработчиков. В Evrone можно работать удалённо с первого дня, мы поддерживаем и оплачиваем участие в Open-source проектах и выступления на конференциях, а расти в грейдах можно с помощью честной системы проверки навыков и менторства.</p> <p><a class="info-button" href="https://jobs.evrone.ru/?utm_source=digest_site&amp;utm_medium=transition&amp;utm_campaign=go_11_22" rel=" noopener" target="_blank">Подробнее</a></p> Fri, 18 Nov 2022 12:05:51 +0000 Evrone digest /20221118 Испытание медными трубами https://digest.evrone.ru/20221019 <img src="/sites/default/files/styles/card_m/public/2022-10/go_10.png?itok=f6i1kAYb" width="960" height="540" alt="Испытание медными трубами" loading="lazy" typeof="Image" /> <br /> <p>Привет, гоферы! Сегодня взглянем на проблему обратной совместимости и кроссплатформенной разработки с помощью Go. Также расскажем про неоднозначный фреймворк Beego и корректный подход к завершению работы приложения.</p> <h2>Graceful Shutdown</h2> <p>О graceful shutdown и hard shutdown мы чаще всего слышим в контексте операционных систем. Первое можно назвать плавным завершением работы: все исполняемые приложения корректно закрываются и только после этого ОС завершает работу. Второе же можно назвать принудительным выключением: ОС прекращает работу вне зависимости от того, успели запущенные приложения завершиться штатно или нет.</p> <p>Golang в этом похож на операционную систему. Здесь тоже есть необходимость корректно завершать работу запущенных задач до отключения приложения. Благо язык предоставляет инструменты, позволяющие отслеживать и обрабатывать сигналы завершения работы от ОС. В стандартной библиотеке есть пакет <a href="https://pkg.go.dev/context" rel=" noopener" target="_blank">Context</a>.</p> <p>Начать стоит с туториала <a href="https://www.digitalocean.com/community/tutorials/how-to-use-contexts-in-go" rel=" noopener" target="_blank">How To Use Contexts in Go от DigitalOcean</a>. Из него вы узнаете, какие функции и методы можно использовать для реализации плавного завершения задач. context.Background создаёт новый контекст на каждый новый процесс. А метод Done() интерфейса Context вместе с фунцией context.WithCancel помогает корректно завершить работу контекста.</p> <p>Чтобы взаимодействовать с сигналами завершения от ОС, потребуется пакет <a href="https://pkg.go.dev/os/signal" rel=" noopener" target="_blank">os/signal</a>. Он также входит в стандартную библиотеку языка и реализует доступ к входящим сигналам ОС. Стоит помнить, что поведение в UNIX-подобных ОС будет отличаться от поведения в Windows или Plan 9.</p> <h2>Кроссплатфор­мен­ность с Fyne</h2> <p>В нашем <a href="https://digest.evrone.ru/flutter" rel=" noopener" target="_blank">дайджесте по Flutter</a> мы не раз отмечали удобство кроссплатформенной разработки. Единая кодовая база для мобильного и десктопного приложения делают жизнь разработчика проще. Но не только Dart может этим похвастаться. У Golang припрятан козырь в рукаве — <a href="https://github.com/fyne-io/fyne" rel=" noopener" target="_blank">Fyne</a>.</p> <p>Это простая библиотека, позволяющая создавать программы с графическим интерфейсом на Go. Вместе с кросс-компилятором <a href="https://github.com/fyne-io/fyne-cross" rel=" noopener" target="_blank">fyne-cross</a> они позволяют собрать приложение почти под любую операционную систему и архитектуру. Обольщаться не стоит — там есть нюансы, которые не дают возможности работы сходу, «из коробки». Но и ничего сложного тоже нет, но без установленного докера адекватно не работает.</p> <p>Вот так будет выглядеть Helloworld, написанный с помощью Fyne:<br /> <br />  </p> package main import ( "fyne.io/fyne/v2/app" "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/widget" ) func main() { a := app.New() w := a.NewWindow("Hello") hello := widget.NewLabel("Hello Fyne!") w.SetContent(container.NewVBox( hello, widget.NewButton("Hi!", func() { hello.SetText("Welcome :)") }), )) w.ShowAndRun() } <p>Этот пример можно запустить как обычно через go run main.go или в режиме симуляции мобильного устройства go run -tags mobile main.go.</p> <p>Заинтересовали? Тогда обязательно прочитайте статью на Хабре <a href="https://habr.com/ru/post/692214/" rel=" noopener" target="_blank">Golang fyne Куда нажать? :-(</a>, где автор подробно описывает свой опыт создания приложений на Fyne. Отдельно отметим, что кроме статьи автор составил <a href="https://github.com/valerijhegaj/fyne-cross-guide" rel=" noopener" target="_blank">краткий гайд по кросс-компиляции</a>.</p> <h2>Go и обратная совместимость</h2> <p>Какое профессиональное сообщество без холивара? Вот и о тему обратной совместимости было сломано немало копий в попытках доказать жизнеспособность той или иной идеи.</p> <p>Сохранение обратной совместимости — один из приоритетов индустрии, ведь это позволяет сохранить функционирование существующих систем. Людям в этом случае не нужно переучиваться или серьезно менять подход к привычной деятельности.</p> <p>С другой точки зрения, сохранение обратной совместимости предполагает сдерживание развития и требует немалых ресурсов. Поддержка старых архитектур и протоколов ставит массу ограничений и часто является недостижимым препятствием на пути прогресса.</p> <p>Развитие языка за последний год показало существенные преобразования в плане переделки архитектуры. Теперь в языке есть <a href="https://digest.evrone.ru/20220322" rel=" noopener" target="_blank">дженерики</a>, появился <a href="https://digest.evrone.ru/20220215" rel=" noopener" target="_blank">фаззинг</a> и в планах внедрение PGO (Profile-guided optimization). В сообществе закономерно начались <a href="https://github.com/golang/go/discussions/55090" rel=" noopener" target="_blank">обсуждения</a> и таких важных вещей, как обратная совместимость.</p> <p>Часть мейнтейнеров Golang указывают, что их цель — достижение полной обратной совместимости с первой версией языка. Это означает большую стабильность для конечных пользователей и <a href="https://go.dev/doc/go1compat" rel=" noopener" target="_blank">задекларировано</a> в документации. Исключения — исправления ошибок и ситуации с нарушением безопасности.</p> <p>Есть и другая, альтернативная точка зрения. Мы видим немало примеров, когда выбор, сделанный в пользу прогресса, и отказ от обратной совместимости позволил добиться хороших результатов. Так Python 3 обзавёлся массой новых функций, код стало удобнее читать и воспринимать. Судя по рейтингам, языку это пошло на пользу.</p> <p>Ждут ли нас глобальные изменения в Golang — покажет время. А пока можно спокойно обдумать всё вышесказанное, а возможно и поделиться своим мнением с коммьюнити.</p> <h2>Фреймворк Beego</h2> <p>В нашем дайджесте мы всегда стараемся рассказывать о самых разных инструментах разработки, даже о неоднозначных. Например, привычную для многих MVC-архитектуру попытались запихнуть в Go. Результатом стали такие фреймворки, как <a href="https://github.com/revel/revel" rel=" noopener" target="_blank">Revel</a> и <a href="https://github.com/beego/beego" rel=" noopener" target="_blank">Beego</a>. О последнем и расскажем чуть подробнее.</p> <p>Tornado, Sinatra и Flask — именно они стали источником вдохновения для автора фреймворка. С помощью Beego можно создавать RESTful API, веб-приложения и серверные службы. Используется принцип «battery included» в отличие от того же Gingonic, то есть в фреймворке есть все необходимые инструменты.</p> <p>Казалось бы, отличная идея совместить скорость и удобство языка с архитектурой MVC. Но реализация получилось неоднозначной. Многие разработчики, часто <a href="https://habr.com/ru/post/444022/" rel=" noopener" target="_blank">критикуют</a> Beego из-за активного использования практик, давно ставших в Go антипаттернами, сложности тестирования и частого возникновения побочных эффектов. Да и создавался Beego во времена, когда о дженериках речи не шло.</p> <p>Итого — можно писать full-stack приложения на Go, используя MVC-архитектуру. Но надо ли?</p> <h2>Подкасты</h2> <h4>Немного IT</h4> <p><a href="https://www.youtube.com/channel/UCzjQIaveGe_G8yT9iFcKwTQ/featured" rel=" noopener" target="_blank">Видеоподкаст про Go</a> снимают и развивают двое наших коллег из Evrone. Они обсуждают его преимущества и недостатки, сравнивают с другими языками.</p> <p>Выпуски длятся 50-70 минут, а значит можно совместить какие-нибудь скучные занятия с обучением. Включайте шумоподавление на наушниках, чтобы не слышать пылесос, и погружайтесь в нюансы Go! Ну а если вам есть что сказать — добро пожаловать в комментарии!</p> <h2 id="article_title_7">Митапы</h2> Онлайн <h3>Осенний Go Meetup</h3> <p>19 октября 2022</p> <p>Рады сообщить, что уже сегодня вечером состоится Go Meetup. Нас ждут интереснейшие доклады спикеров:</p> <ul> <li aria-level="1">Антон Губарев (Авито) — «Реализация ролевой системы доступа с помощью Open Policy Agent».</li> <li aria-level="1">Николай Тузов (Lamoda) — «Внутреннее устройство каналов в Go».</li> <li aria-level="1">Андрей Беренда (Ozon Fintech) — «Ошибки, которые нельзя обработать в Golang».</li> </ul> <p>Ещё не поздно зарегистрироваться и принять участие в мероприятии.</p> <p><a class="info-button" href="https://meetups.evrone.ru/go-meetup-online-1?utm_source=digest_site&amp;utm_medium=transition&amp;utm_campaign=go_10_2022" rel=" noopener" target="_blank">Регистрация</a></p> <p> </p> <h2 id="article_title_8">Вакансии</h2> <span>Удаленка / Офис</span> <h3>Evrone </h3> <p>Мы открыты для новых Go-разработчиков. В Evrone можно работать удалённо с первого дня, мы поддерживаем и оплачиваем участие в Open-source проектах и выступления на конференциях, а расти в грейдах можно с помощью честной системы проверки навыков и менторства.</p> <p><a class="info-button" href="https://jobs.evrone.ru/?utm_source=digest_site&amp;utm_medium=transition&amp;utm_campaign=go_10_2022" rel=" noopener" target="_blank">Подробнее</a></p> Wed, 19 Oct 2022 11:52:58 +0000 Evrone digest /20221019