Взгляд со стороны

04 августа 2022
Взгляд со стороны

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

Визуализация глобальных блокировок

Мы пишем код и редко задумываемся, что же из себя представляет интерпретатор. В случае с виртуальной машиной Ruby — это большое и сложное приложение, написанное на языке C (мы не говорим сейчас о JRuby или TruffleRuby). Загвоздка в том, что это приложение мультипоточное и подвержено ошибкам параллелизма. Для корректной работы нескольких потоков используется стратегия глобальной блокировки интерпретатора.

В Python эта стратегия называется GIL (Global Interpreter Lock), а в Ruby принято обозначение GVL (Global VM Lock). Суть же приблизительно одинаковая. Когда мы даём потоку выполнять руби код, то он должен блокировать другие потоки от выполнения руби кода. Поток сообщает виртуальной машине, что стал активным. Это в свою очередь гарантирует отсутствие изменения объектов другими потоками.

Так написанный код на Ruby может работать параллельно (но не одновременно!) над несколькими задачами, обеспечивая независимый от операционной системы уровень параллелизма. Ещё раз: на уровне интерпретатора единовременно будет работать только один поток Ruby. 

Но ведь это же виртуальная машина, а значит их может быть много? Формально глобальной блокировки VM не существует, а с третьей версией Ruby доступен такой примитив параллелизма, как Ractors. Так можно отвязаться от единственного потока исполнения.

Чтобы получить больший контроль над состоянием GVL был создан gem gvl-tracing. Этот пакет даёт пользователям возможность детально наблюдать, как их мультипоточный код использует блокировки GVL. Фактически — это удобный способ взаимодействия с GVL Instrumentation API, созданного разработчиком Жаном Бусье. Единственный недостаток пакета — он требует самой свежей версий Ruby, начиная с preview-версии 3.2.

Визуализация работы механизма GVL поможет увидеть конкурентную борьбу между потоками, которая в результате может быть устранена через внедрение Ractors. Так что мы получим параллелизм не только внутри, но и снаружи, поскольку потоки Ruby VM будут действовать независимо и не мешать друг другу. Скорее всего результат вас приятно удивит. Если ничего не упадет :)

В стиле Hanami

Скорость никогда не была сильной чертой Ruby, о чём в деталях рассказывал наш DevRel Григорий Петров. Использование больших и функциональных фреймворков лишь усугубляет ситуацию. Было неизбежно появление легковесных фреймворков, заточенных на малое потребление памяти и оптимизированных для достижения высокой скорости. Яркий пример — веб-фреймворк Hanami

В переводе с японского языка Hanami дословно означает «любование цветами» (hana — цветок, mi — смотреть). Это стало традицией в Японии, где цветут чрезвычайно красивые цветы вишни сакуры. Период цветения очень короткий, поэтому каждый житель страны восходящего солнца считает необходимостью устроить небольшой пикник под цветущими деревьями. 

Простота, безопасность и минимализм — вот три основных качества Hanami, крайний релиз которого был выпущен осенью 2021 года. Но работа над проектом не останавливается и совсем недавно была анонсирована первая бета-версия Hanami v2.0.0.

Исходя из анонса, становится ясно, что Hanami сильно меняется, делая упор на более проработанную структуру веб-приложения. Также авторы включили три команды CLI, позволяющие быстро создать приложение, запустить веб-сервер и вывести на экран роуты. Первой выйдет версия 2.0, которая будет нести основные изменения, а затем 2.1, которая по замыслу разработчиков будет полностью завершенной. Так что советуем полюбоваться цветами и поддержать создателей звёздочкой на GitHub.

There is no spoon…

Молодые разработчики знакомятся с понятием логического типа практически сразу же, как начинают изучать какой-либо язык программирования. Со временем их опыт и квалификация вырастает, а понятия true/false для них так и остаются простой и понятной сущностью. 

Что если привычные логические типы всего лишь абстракция? Конструктор для соответствующих классов? В Ruby — это TrueClass и FalseClass. Если «забраться в кроличью нору», то мы увидим, как именно работает система таких абстракций. 

Взглянем, что из себя представляет логическое значение в Ruby. Это либо false, либо nil, либо… идентификатор объекта. Каждый объект в Ruby пронумерован и виртуальная машина иногда использует эти числа для выполнения оптимизации. Если копнуть глубже, внутри лежат особенности языка C. Там все логические значения — это числа. 0 — ложное значение, все остальные числа — истинное. Что в целом и позволяет с помощью if/unless однозначно определять логическое значение.

Немного об утечках памяти

Утечка памяти всегда ведёт к безвременной гибели приложения от рук OOM Killer. Так что надо уметь выявлять и устранять это явление. Начнём с основ — поймём, как Ruby управляет памятью.

Все объекты помещаются на хранение в «кучу». 1 объект = 1 слот. По умолчанию размер кучи 10 000 слотов. До версии Ruby 3.1 размер слота был фиксированным, а именно 40 байт. Начиная с 3.1 для некоторых объектов, таких как String, вводится переменная ширина. Смысл в том, чтобы дать возможность 1 объекту занимать более 1 слота, то есть улучшить локализацию данных и упростить управление памятью.

Выше мы уже упоминали о том, что Ruby VM — это большое приложение на C. Так что получается у нас не одна «куча», а целых две. Одна принадлежит самому Ruby, которая хранит там объекты малого размера, а вторая языку C (malloc), куда складируются более крупные объекты. Если каждый объект сможет занимать более 1 слота в «куче» под управлением Ruby, то от второй «кучи» можно будет отказаться.

Заполнение всех доступных слотов в конечном итоге приводит к вызову сборщика мусора и остановке всех иных процессов. Далее всё зависит от того, какой режим работы поможет освободить память. Первый, Minor GC, посмотрит только на недавно созданные объекты и попытается освободить достаточное количество слотов. Если сей трюк не сработает, то вызывается второй режим — Major GC. Он переберёт все созданные объекты и также попытается освободить слоты. И только если оба режима не смогут решить вопрос — размер «кучи» будет увеличен.

Утечка памяти — это как раз ситуация при которой ваш код создаёт объекты, которые не удаляются сборщиком мусора. Это приводит к более частому его вызову и постоянному увеличению размера «кучи». Как только GC попытается выделить памяти, более чем доступно в системе, приложение вылетит. Пока звучит сложно, поэтому советуем прочитать эту статью, где детально разобрано, как мониторить и устранять утечки памяти.

Митапы и конференции

Онлайн

Ruby Russia

Мы закрыли Сall For Papers и выбрали 14 докладов, которые войдут в программу конференции. Скоро эти доклады будут анонсированы на официальном сайте — регистрируйтесь и присоединяйтесь к нашей онлайн-конференции 30 сентября и 1 октября.

Полторы тысячи коллег-рубистов, заранее отснятые в студии доклады кинематографического качества и прямой эфир из Сколково: всё, чтобы собраться и обсудить интересующие вас темы из мира Ruby разработки!

Регистрация

 

Онлайн

Ruby meetup №18

 19:00

Рады сообщить, что у нас запланирован Ruby Meetup, который пройдёт 14 сентября 2022. Все доклады будут традиционно предзаписаны в 4К, а вести митап в прямом эфире и помогать вам допрашивать спикеров в чате будет Григорий Петров, Ruby-разработчик и организатор конференции RubyRussia. 

Детальная информация о мероприятии будет опубликована позже, следите за нашими новостями. Кстати, если у вас есть идея доклада и вы хотите стать спикером, то пишите на почту andy@evrone.com.

Регистрация

 

Если же вы пропустили наше предыдущее мероприятие, то видеозаписи докладов уже выложены в сети. Вот какие вопросы на нём были.

Наш коллега, Никита Богомолов рассказал про межсервисное взаимодействие и организацию очередей сообщений:

 

Антон Давыдов (Solution Architect) поведал о своём опыте правильного использования событийной модели в сервисах и о том, как выстроить архитектуру приложения:

 

Ruby-разработчик, Андрей Молчанов поделился опытом снапшот-тестирования и почему это самый недооценённый подход к тестированию:

Конкурсы для разработчиков

Онлайн

Ruby Quiz

до 22 августа 2022

Evrone любит Ruby, и, кажется, это взаимно. Проверить, насколько тесные отношения связывают с Ruby вас, можно в нашем квизе. Его составляли наши опытные разработчики, так что придётся хорошо подумать. Семь вопросов внутри касаются Ruby 3.1 и Rails 7.0, если не указано иное. Если правильно ответить на все или почти все вопросы, можно выиграть приятный приз — Яндекс Станцию. Победителя определит генератор случайных чисел в прямом эфире на нашем YouTube-канале.

Принять участие

Вакансии

Удаленка / Офис

Evrone 

Мы открыты для новых Ruby-разработчиков. В Evrone можно работать удалённо с первого дня, мы поддерживаем и оплачиваем участие в Open-source проектах и выступления на конференциях, а расти в грейдах можно с помощью честной системы проверки навыков и менторства.

Подробнее

Подписаться
на Digest →
Важные новости и мероприятия без спама
Технологии которыми вы владеете и которые вам интересны
Ваш адрес электронной почты в безопасности - вот наша политика конфиденциальности.