Rails 6 に Sidekiq を導入してジョブを定期実行する記事。
背景
dev モードの Tapyrus で ブロック生成コマンドを定期実行すれば、なんちゃってオレオレテストネットが作れるのでは?
Sidekiq
Sidekiq は 非同期ジョブ実行のためのフレームワーク。データストレージは Redis を利用する。
導入
Gemfile 追記
gem 'sidekiq' gem "sidekiq-cron"
ActiveJob queue adapter に Sidekiq を指定
# Use Sidekiq as ActiveJob queue adapter config.active_job.queue_adapter = :sidekiq
Sidekiq の設定
:concurrency: 25 :pidfile: ./tmp/pids/sidekiq.pid :logfile: ./log/sidekiq.log :queues: - default - mailers - active_storage_analysis - active_storage_purge :daemon: true
起動時に 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
実際に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
generate_block_job: cron: "*/1 * * * *" class: "GenerateBlockJob" description: "1分毎にブロックを生成する"
次に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