最近個人的にバックグラウンドワーカーとしてSolidQueueを使う機会が少しずつ増えています。そんな折SolidQueueのv1.3.0がリリースされたのですが、その中に個人的に興味深い機能が入ったので紹介しておきます。
前提
SolidQueueには複数の役割が定義されています。
- Supervisor
- Dispatcher
- Scheduler
- Worker
SolidQueueは開発初期では それぞれの役割がスレッドとして1プロセス内でも動くasync modeが用意されていました
が、実装をシンプルにするためにv0.4.0以降はasync modeが廃止され、各役割ごとに1以上のプロセスを割り当てるようになっています。
SolidQueueはメモリ消費量がSidekiqよりも多かった
各役割ごとにプロセスが割り当てられるため、SolidQueueを利用する際には最低限の構成でも3〜4プロセス作られることになります*1。Sidekiqは1プロセスで動くので、Sidekiqだと問題ないサーバでもSolidQueueだとメモリが厳しいことが起こります。
ぼくもHerokuで512MBメモリのdynoを利用しworkerを運用していたのですが、SidekiqからSolidQueueへ移行する際にはメモリが足らず1GBメモリのdynoにアップグレードせざるを得ませんでした。
Railsは個人開発者が安いVPSを借りて簡単にデプロイし運用することができ大変便利なのですが、SolidQueueを利用する場合、メモリに関してはある程度大きめなもの(2GB〜)が必要になっていました。
async modeの復活
このメモリ消費量の問題で、async modeの復活をしたいという人が現れました。メモリ消費量を減らしたい!という要望だけではなかなか物事が前に進まなかったのですが、これまでforkが使えないのでSolidQueueを利用できなかったJRubyやWindows環境の人もSolidQueueを使えるようにしたい、というところで話が前に進んだようです。
そしてついにasync modeを復活させるPR がマージされました。このコミットは先日リリースされたv1.3.0に含まれています。
bin/jobs --asyncで起動するか、SOLID_QUEUE_SUPERVISOR_MODE=asyncとするとasync modeを利用するようになります。
READMEに次のように書かれているので、基本的にはプロセス(fork)を使う方が挙動が安定しそうですが、個人開発など限られた環境で使う分には便利ではないでしょうか。
The recommended and default mode is
fork. Only useasyncif you know what you're doing and have strong reasons to
僕の環境でも600MBを超えていたメモリ消費量を260MBくらいまでに減らすことができました。やったね。

*1:Schedulerはrecurring jobが必要なければ使わない