Что такое Dry-rb, и как он поможет с Ruby приложением там, где не может помочь Ruby on Rails

Illustration of a person standing at a bookshelf filled with books, some labeled 'dry-rb,' with a desk showcasing an open laptop displaying a 'Rails' error message, a lamp, and a printer. Illustration of a person standing at a bookshelf filled with books, some labeled 'dry-rb,' with a desk showcasing an open laptop displaying a 'Rails' error message, a lamp, and a printer.

Я работаю в стартапе. Делаем самый прибыльный майнинг-пул с умным алгоритмом переключения. Сам пул написан на языке программирования Go, а для внутренних сервисов используем Ruby. Приложения крутятся в контейнерах, используется микросервисная архитектура. Несмотря на то, что стартап, мы стараемся не забывать о качестве кода и используем TDD: лучше спать меньше, но спокойно.

Почему нам не подходит Ruby on Rails?

С увеличением количества сервисов всё более явным становилось, что Rails, несмотря на простоту и скорость разработки, в нашем случае создаёт больше проблем, чем решает. Ниже несколько примеров сложностей, с которыми мы столкнулись.

Усложнённая архитектура

Во-первых, наши сервисы намного больше похожи на простые программы, нежели на традиционные Rails-приложения. Типичные задачи – считать статистику, мониторить сеть блокчейна, вычислять награды пользователей и отправлять транзакции. Пример API – список транзакций пользователя. Получалось, что внутри папки app появился какой-то огромный мир. Это было поддерживаемо, но мысль о том, что где-то мы свернули не туда, не покидала.

Сложности в использовании тредов

Другая проблема, с которой мы столкнулись – асинхронность. Мы много используем в коде треды, и если не выполнять preload всего приложения, регулярно получали ошибки autoload. С этим можно мириться, да и от предзагрузки приложения в тестовой среде никто не умирал. Но я считаю, что такой проблемы не должно быть в принципе – треды и без такого не дают заскучать.

Неиспользуемые зависимости

Нельзя не упомянуть большой итоговый вес приложения. Сейчас от пуша в master до развёртки новой версии на стейдже у нас проходит 50 секунд. За это время успевают пройти тесты, собирается и отправляется в registry образ. Раньше этот же цикл занимал минимум 4 минуты. Другим бонусом стало то, что теперь тесты и консоль загружаются за секунду. Очень приятная мелочь в повседневной работе, как оказалось.

Высокое потребление памяти

Наконец, мы стали банально упираться в память. Мы держим по два воркера каждого сервиса, со временем это стало достаточно затратно. Теперь же в среднем сервисы потребляют в 8 раз меньше памяти, чем они же, написанные на Rails.

Как мы решили свои проблемы?

Учтя всё вышеперечисленное и множество других мелких сложностей, было решено перейти на стек от сообщества dry-rb. Ruby on Rails же мы оставили для API-heavy сервисов, которые было долго переписывать. Мы не считаем, что Rails мёртв, он лишь не подходит для наших задач.

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

Теперь в своих проектах мы используем большую их часть: dry-system, dry-web, dry-transaction, dry-validation, dry-types, dry-struct, dry-monads. Этим мы решили проблемы, которые я описал выше. Но это далеко не всё, что мы получили. Приложения стали мало весить, делятся на полностью изолированные компоненты и проще тестируются. Увеличилась общая компетенция команды, появился дополнительный интерес к работе. Последнее я считаю важным фактором: горящие глаза коллег – залог отличной атмосферы в офисе. Подробнее о том, как мы используем данные решения в своих проектах, можно прочитать в следующих частях этого цикла: