patorashのブログ

方向性はまだない

開発環境で複数のRailsアプリを起動する場合はActiveJobのキュー名に気を付けよう

アプリ連携を作っていた時に起きた現象なので、複数Railsアプリを起動する場合は気をつけましょう。

FooアプリとBarアプリがあって、どちらもActiveJobを使っていました。どちらもqueueの名前はdefaultのままにしていました。そして、同じRedisを共有していました。

こっちはFooアプリのジョブ。

class FooJob < ApplicationJob
  queue_as :default

  def perform
    puts "Foo"
  end
end

こっちはBarアプリのジョブ。

class BarJob < ApplicationJob
  queue_as :default

  def perform
    puts "Bar"
  end
end

そして、FooアプリもBarアプリもsidekiqを起動。

bundle exec sidekiq

これで、BarJob.perform_laterを実行したところ、Fooアプリ側のログにclass BarJobが定義されていないというログが出てきました。 キュー名がどちらもdefaultのため、どちらのジョブか判別する術がありません。

キュー名にprefixをつける

ActiveJobは設定でキュー名にprefixをつけることができるので、つけておきましょう。

今回は開発環境だけでキュー名を分けたかったので、Fooアプリ側のconfig/environments/development.rbを以下のように修正しました。

Rails.application.configure do
  config.active_job.queue_adapter = :sidekiq
  config.active_job.queue_name_prefix = "foo_#{Rails.env}"
end

同様に、Barアプリ側のconfig/environments/development.rbも修正。

Rails.application.configure do
  config.active_job.queue_adapter = :sidekiq
  config.active_job.queue_name_prefix = "bar_#{Rails.env}"
end

sidekiqに処理するキュー名を教える

今までのままだと、キュー名がdefaultのもののみを処理しようとするので、キュー名を教える必要があります。

CLIで指定する

Fooアプリ側は以下のように。

bundle exec sidekiq -q foo_development_default

Barアプリ側も同様に。

bundle exec sidekiq -q bar_development_default

設定ファイルで指定する

CLIで毎回キュー名を打つのは面倒なので、config/sidekiq.ymlを定義しました。デフォルトはprefixなしですが、developmentの場合だけprefixが付いたキュー名にしました。

2021-03-16 追記

(ここから)
ActionMailerでdeliver_laterを使って非同期メール送信する際に、以前のキューの設定では動かないことがわかりました。mailersを追記するように修正しています。
(ここまで)

これは、Fooアプリ側。

---
:queues:
  - default
  - mailers

:concurrency: <%= ENV.fetch('SIDEKIQ_CONCURRENCY', 5) %>

development:
  :queues:
    - foo_development_default
    - foo_development_mailers

同様に、Barアプリ側も。

---
:queues:
  - default
  - mailers

:concurrency: <%= ENV.fetch('SIDEKIQ_CONCURRENCY', 5) %>

development:
  :queues:
    - bar_development_default
    - bar_development_mailers

これで、各Railsアプリ同士でキュー名が干渉することはなくなりました。