Solid Queue 1.6.0 получила воркеры на файберах для I/O-задач и LLM-запросов

Solid Queue 1.6.0 получила воркеры на файберах для I/O-задач и LLM-запросов

Solid Queue, библиотека фоновых задач (job queue) для Rails, выпустила версию 1.6.0. Главное нововведение релиза, режим выполнения воркеров на файберах, который добавил разработчик под ником crmne (это его первый вклад в проект). Раньше воркер обрабатывал задачи в пуле из нескольких потоков; теперь вместо этого можно запускать задачи на файберах, лёгких единицах выполнения на одном потоке-реакторе. Чтобы включить режим, в конфигурации воркера вместо количества потоков указывается количество файберов, например: очередь "api*", 100 файберов, интервал опроса 0.05 секунды. Под капотом режим использует gem Async, поэтому его нужно добавить в зависимости проекта. Также требуется включить изоляцию файберов в самом Rails, параметр config.active_support.isolation_level = :fiber. По словам авторов релиза, такой режим может быть очень полезен для задач, упирающихся в ввод-вывод (I/O-bound), в том числе для обращений к LLM. В релиз вошли и другие изменения: разработчик rosa исправил откат транзакций, которые оставались незакрытыми после того, как поток с задачей убивали в тестах; ещё один новый участник проекта, wintan1418, добавил документацию о том, как обновлять динамические повторяющиеся задачи. Полный список изменений покрывает диапазон от версии v1.5.1 до v1.6.0.

Ключевые факты

  • Solid Queue 1.6.0 добавила режим воркеров на файберах вместо классического пула потоков
  • В конфигурации воркера вместо параметра threads указывается fibers (в примере релиза, 100 файберов при polling_interval 0.05 секунды)
  • Для работы режима нужен gem Async и включённая в Rails изоляция файберов (config.active_support.isolation_level = :fiber)
  • Авторы отмечают пользу режима для I/O-задач, включая обращения к LLM
  • В релиз также вошли фикс отката транзакций, оставленных убитыми потоками задач в тестах, и документация по обновлению динамических повторяющихся задач

Почему это важно

Файберы, это лёгкие единицы выполнения внутри одного потока: переключение между ними намного дешевле, чем между потоками операционной системы. Для задач, которые почти всё время ждут ответа по сети (типичный случай, вызов LLM-API), это означает, что один воркер-процесс сможет одновременно вести гораздо больше таких задач, чем при классическом пуле потоков, не упираясь в накладные расходы на сами потоки. Именно поэтому в release notes отдельно упомянуты сценарии с обращениями к LLM.

Кому это важно

Прежде всего разработчикам на Ruby on Rails, которые используют Solid Queue для фоновых задач, и особенно тем, кто добавляет в приложение функции на основе LLM, например, фоновую обработку запросов к ИИ-сервисам, где задача большую часть времени простаивает в ожидании ответа от внешнего API.

Как это применить

Чтобы перейти на новый режим, в конфигурации воркера нужно заменить параметр threads на fibers и указать нужное число файберов (в примере из релиза, 100 при polling_interval 0.05 секунды). Дополнительно требуется добавить в зависимости gem Async, на котором построен режим, и включить в Rails изоляцию файберов через config.active_support.isolation_level = :fiber. Без этого условия режим работать не будет.

Можно ли доверять

Источник, официальные release notes проекта Solid Queue на GitHub, это самое надёжное описание изменений в самой библиотеке. При этом в тексте релиза нет ни одного числа с замерами производительности: авторы не публикуют сравнение пропускной способности файберного режима с режимом на потоках, поэтому насколько сильно ускоряется обработка I/O-задач на практике, по этому релизу судить нельзя.

Риски и подводные камни

Новый режим тянет за собой дополнительную зависимость (gem Async) и требует включить изоляцию файберов на уровне всего Rails-приложения, это системная настройка, а не локальный флаг только для очереди задач, и её последствия для остального кода release notes не разбирают. Сам механизм фиберной изоляции в Rails и то, с какой версии Rails или Ruby он доступен, в тексте релиза тоже не описаны. Функцию добавил новый для проекта участник (это его первый вклад в Solid Queue), что само по себе не проблема, но стоит иметь в виду при оценке зрелости кода.