2020年4月18日土曜日

Rails6 + Sidekiq 超入門

概要

前回 Rails6 と PostgreSQL を使って簡単な Web アプリを作ってみました
今回は Rails6 と Sidekiq を組み合わせて非同期な Web アプリを作ってみます

Redis のインストール

  • brew install redis
  • brew services start redis

Sidekiq のインストール

rails new で作成したアプリ配下にある Gemfile を編集します

  • vim Gemfile
gem "sidekiq"
  • bundle install

Sidekiq の初期化

config/initializers/sidekiq.rb を作成してここに Redis のエンドポイントなど Sidekiq の初期化に必要なパラメータなどを設定します

  • vim config/initializers/sidekiq.rb
Sidekiq.configure_server do |config|
  config.redis = { url: 'redis://localhost:6379/0' }
end

Sidekiq.configure_client do |config|
  config.redis = { url: 'redis://localhost:6379/0' }
end

Worker の作成

app/workers 配下に作成します
デフォルトだとディレクトリが存在しないので作成します
ワーカーのファイル名は名前はワーカークラス名のスネークケースで作成します

  • mkdir app/workers
  • vim app/workers/wait_worker.rb
class WaitWorker
  include Sidekiq::Worker

  def perform(time, params)
    sleep time
    my_task = MyTask.new
    params = JSON.parse(params)
    my_task.title = params["title"]
    my_task.description = params["description"]
    my_task.public = params["public"]
    my_task.updated_date = Time.now
    if my_task.public
      my_task.posted_date = Time.now
    end
    my_task.save
  end
end

Sidekiq を経由すると params の Rails 側アプリとは少し異なる点に注意してください
後述していますがハッシュを JSON 文字列に変換してから Sidekiq に渡しています
やっていることは前回のタスクを登録する処理と同じです

エンキューする処理の実装

Rails アプリ側でエンキューするようにしましょう
コントローラを修正します

  • vim app/controllers/my_tasks_controller.rb
class MyTasksController < ApplicationController
  protect_from_forgery

  def list
    @my_tasks = MyTask.order(posted_date: "DESC").all
  end

  def show
    id = params[:id]
    @my_task = MyTask.find(id)
  end

  def create
    WaitWorker.perform_async(5, params.to_json)
    redirect_to '/my_tasks'
  end
end

1 つポイントがあり Sidekiq にハッシュ値を渡したい場合は一旦 JSON 文字列に変換する必要があります
そしてワーカー側で JSON 文字列からハッシュに再度変換します
今回は適当に遅延させたいので 5 秒ウェイトしてから DB に INSERT します

動作確認

まずはワーカーを起動します

  • bundle exec sidekiq

そして Rails アプリを起動しましょう

  • rails server

あとはタスクを作成してみましょう
5 秒ほど遅延があってからデータが挿入されるのが確認できると思います

最後に

Rails6 + Sidekiq を試してみました
Rails 上で使う場合はディレクトリ構成が決まっているのでその点だけ注意が必要かなと思います
Rails 上の場合は require 系が不要なのが記述が少なく済むので嬉しいのかなと思います

参考サイト

0 件のコメント:

コメントを投稿