
Solid Queueで非同期処理を導入する方法
railsのバージョン7.1からSolid Queueが使えるようになりました。
これはRedisなどなくてもSqliteが動くところであれば、非同期処理を使うことができる代物。
レンタルサーバーやVPSなど1台構成でもRedisなど入れずに非同期処理を気軽に使うことができるようになります。
まずはローカル環境でSolid Queueを動かせるように設定していきましょう。
セットアップ
rails newを実行した時にsolid_queueを一緒にインストールしていない場合は以下を実行してインストールをしましょう。
これで設定ファイルが新規作成されたり、設定項目が追記されたりします。
$ bundle add solid_queue
$ bin/rails solid_queue:install
developmentの設定を追記する
config/database.ymlのdevelopmentの部分にproductionと同じようにqueueの設定を追記します。
queue用のデータベースを作成するようにします。
development:
primary:
<<: *default
database: storage/development.sqlite3
queue:
<<: *default
database: storage/development_queue.sqlite3
migrations_paths: db/queue_migrate
次にconfig/development.rbにsolid_queueを使うように設定を入れます。これもproduction.rbと同じです。
# Highlight code that enqueued background job in logs.
config.active_job.verbose_enqueue_logs = true
# 以下2行を追記
config.active_job.queue_adapter = :solid_queue
config.solid_queue.connects_to = { database: { writing: :queue } }
active_jobを使う
下準備ができたので、active_jobを使ったコードを書いていきます。
app/jobsにjobを実行するためのクラスを作成しましょう。ここまでくればsolid_queueを意識する部分はなくなります。
たとえば、ユーザーに完了メールを非同期で送るコードはこんな感じに書けると思います。
class UserThanksMailerJob < ApplicationJob
def perform(user_id)
UserThanksMailer.send_mail(user_id)
end
end
あとは、このJobクラスを任意の場所から非同期で呼び出してあげればOKです。
UserThanksMailerJob.perform_later(user_id)
サーバーを起動させる
初回はsolid_queue用のデータベースが必要です。db:prepareを実行しましょう。
そして、環境変数のSOLID_QUEUE_IN_PUMAを指定してbin/devを実行することでqueueの管理を受け付ける状態で開発サーバーが起動します。
$ bin/rails db:prepare
$ SOLID_QUEUE_IN_PUMA=true bin/dev
またはbin/jobsを実行してqueueを管理するためのプロセスを立ち上げることも可能です。
この方法はqueue用のサーバーやコンテナをフロントとは別に用意して待機させる構成の場合使うことになるでしょう。本番などはこっちの出番が多そうです。
$ bin/jobs
これで SolidQueue-1.1.3 Register Supervisor〜
のようなメッセージがbin/devの実行ログに表示されてくれば、queueが動いていることになります。
queue用のデータベースにデータが挿入されている様子も確認できるでしょう。
気軽にQueueを使えるのがいいですね!sqliteじゃなくて、MySQLやPostgreSQLも使えます。
Solid Queueは本番で非同期処理を実現するための選択肢としても十分あり得ると思いました。