LoginSignup
1
1

More than 3 years have passed since last update.

Rails6にdelayed_jobでメールの非同期実行を実装し、AmazonLinux2のマルチDockerのコンテナで動かす

Posted at

新規サービスの立ち上げでメールの非同期実行処理を実装するのに、delayed_jobを使う。
まだユーザーも多くないし、実装やお金の面でもとりあえず低コスト。
AWSのElasticBeanstalkでAmazonLinux2のマルチDokckerプラットフォームでの実装の備忘録。

前提

  • docker for mac でrailsアプリケーションを動作させていること。
  • アプリケーションのコンテナ名をwebとし、docker-compose run --rm webのエイリアスを dcrw として登録していること。(コマンドで使っているので読み替えて下さい。)

delayed_jobの基本的な実装

Gemfile
gem 'delayed_job_active_record'
gem 'devise-async'  # devise のメールを非同期実行するのに必要。
docker-compose build
dcrw rails g delayed_job:active_record
dcrw rails db:migrate

bin/delayed_job が生成される。
delayed_jobsテーブルがcreateされる。

que_adapterを設定。

config/application.rb
config.active_job.queue_adapter = :delayed_job

コンテナとして起動。
本番用のdocker-compose.ymlもこれに準拠。

docker-compose.yml
version: '3'
services:  # webコンテナとworkerのコンテナを共通化。
  app:
    build: .
...
  web:
    extends:
      service: app
    command:
        ["sh", "-c", "rm -f tmp/pids/server.pid; bin/rails server -b 0.0.0.0"]
    ...
  jobworker:  # このコンテナを追加。
    extends:
      service: app
    command: bundle exec bin/rails jobs:work
...

参考

deviseのメール対応

これだけだとdeviseが送信するメールは非同期処理の対象にならない。
devise-asyncgemをインストールし、deviseを適用しているモデルのdeviseの設定に:asyncを追加。
Readmeで書かれているオプションのDevise::Async.enabled = trueだけでは非同期にならず。

  devise :database_authenticatable,
         :recoverable, :rememberable, :validatable,
         :async  # 追加

参考

Rspecでキューイングしたメールのテストを行う

細かいことは参考のリンク先参照。
メールの本文までテストするのに、キューに入れたメールを実行する必要がある。
perform_enqueued_jobs メソッドを使う。

spec/rails_helper.rb
RSpec.configure do |config|
  config.include ActiveJob::TestHelper  # 追加
end

specのメール送信処理をperform_enqueued_jobs ブロックで囲う。

spec/feature/xxx_spec.rb
...
expect {
  perform_enqueued_jobs { click_button '送信する' }
}.to change { ActionMailer::Base.deliveries.size }.by(1)

mail = ActionMailer::Base.deliveries.last
expect(mail.subject).to have_content('メールタイトル')
expect(mail.body).to have_content('メール本文…')
参考

AWSでのエラー備忘録

AWSにデプロイした際に、コンテナが落ちる現象が発生。
ログの出力を制御できていなくて時間食ったが、アプリケーションのログにエラーを吐いていた。
docker logs [docker id] するとアプリケーションのログが見れる。
原因はDBに接続していなかったこと。
ENVの設定が必要だった。

参考
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1