Rails に Sidekiq を導入する

Rails 6 に Sidekiq を導入してジョブを定期実行する記事。

背景

dev モードの Tapyrus で ブロック生成コマンドを定期実行すれば、なんちゃってオレオレテストネットが作れるのでは?

Sidekiq

Sidekiq は 非同期ジョブ実行のためのフレームワーク。データストレージは Redis を利用する。

導入

Gemfile 追記

gem 'sidekiq' gem "sidekiq-cron"
Gemfile

ActiveJob queue adapter に Sidekiq を指定

# Use Sidekiq as ActiveJob queue adapter config.active_job.queue_adapter = :sidekiq
config/application.rb

Sidekiq の設定

:concurrency: 25 :pidfile: ./tmp/pids/sidekiq.pid :logfile: ./log/sidekiq.log :queues: - default - mailers - active_storage_analysis - active_storage_purge :daemon: true
config/sidekiq.rb

起動時に sidekiq-cron が config/sidekiq_schedule.yml を読み込むよう設定

# frozen_string_literal: true Sidekiq.configure_server do |config| config.redis = { url: ENV['REDIS_URL'] } config.on(:startup) do schedule_file = 'config/sidekiq_schedule.yml' Sidekiq::Cron::Job.load_from_hash YAML.load_file(schedule_file) if File.exist?(schedule_file) end end Sidekiq.configure_client do |config| config.redis = { url: ENV['REDIS_URL'] } end
config/initializers/sidekiq.rb

実際にJobを作ってみる。

# frozen_string_literal: true class GenerateBlockJob < ApplicationJob queue_as :default def perform(*_args) return unless Tapyrus.chain_params.dev? # Generate block to UTXO Provider's address utxo_provider_address = Glueby::UtxoProvider.instance.address aggregate_private_key = ENV['AUTHORITY_KEY'] Glueby::Internal::RPC.client.generatetoaddress(1, utxo_provider_address, aggregate_private_key) # Start BlockSyncer # source: https://github.com/chaintope/glueby/blob/master/lib/tasks/glueby/block_syncer.rake#L17 latest_block_num = Glueby::Internal::RPC.client.getblockcount synced_block = Glueby::AR::SystemInformation.synced_block_height (synced_block.int_value + 1..latest_block_num).each do |height| Glueby::BlockSyncer.new(height).run synced_block.update(info_value: height.to_s) end end end
app/jobs/generate_block_job.rb
generate_block_job: cron: "*/1 * * * *" class: "GenerateBlockJob" description: "1分毎にブロックを生成する"
config/sidekiq_schedule.yml

次にSidekiqの実行環境を整える。

ローカルの場合

# redis のインストールと起動 $ brew install redis $ brew services start redis # sidekiq の起動 $ bundle exec sidekiq -C config/sidekiq.yml

ENV['REDIS_URL'] をよしなに設定する。

Docker の場合

services: web: # 省略 sidekiq: build: . environment: REDIS_URL: redis://redis:6379 command: bin/bundle exec sidekiq -C config/sidekiq.yml depends_on: web: condition: service_healthy redis: condition: service_healthy redis: image: redis:latest environment: TZ: Asia/Tokyo healthcheck: test: [ "CMD", "redis-cli", "ping" ] interval: 10s timeout: 10s retries: 30 volumes: - redis:/data volumes: redis:

以上!

おまけ)development で Sidekiq のダッシュボードを表示

if Rails.env.development? require 'sidekiq/web' require 'sidekiq/cron/web' mount Sidekiq::Web => '/sidekiq' end
config/routes.rb

参考