1
votes

I'm attempting to send multiple emails at once using Devise::Mailer. Using Devise Async, I would like to queue these emails rather than slow down the entire system by sending them altogether (which can delay the app by about 20 seconds). The main issue seems to be that the devise_async gem does not seem to be communicating with sidekiq at all (I don't see anything in the sidekiq logs).

After much digging, the main difference from what I have and what is in the devise_async wiki, is that the devise_async.rb file was missing parameters (unfortunately, this still does not solve the problem).

EDIT:

The problem might possibly be that I don't have a sidekiq worker--though the devise_async documentation doesn't talk about this. Do I need to trigger the sidekiq worker which would then trigger the UserMailer? I was under the impression that the UserMailer was itself a worker.

devise_async.rb

Devise::Async.setup do |config|
  config.enabled = true
  config.backend = :sidekiq
  config.queue   = :default
end

sidekiq.yml

:verbose: true
:concurrency: 25
production:
  :concurrency: 20
:queues:
  - [mailer, 5]
  - [default, 5]

devise.rb

config.mailer_sender = '[email protected]'
config.mailer = 'UserMailer'

user.rb

after_create :send_email_notification

devise :database_authenticatable, :registerable, :timeoutable,
         :recoverable, :rememberable, :trackable, :validatable, :async

def send_email_notification
        user = User.find(id)
        team = Team.find(user.team_id)

        team.memberships.each do |membership|         
            UserMailer.notification_email(user, team, membership).deliver_later
        end
    end

user_mailer.rb

class UserMailer < Devise::Mailer
    default from: "[email protected]"

    def notification_email(current_user, team, membership)
        @user = current_user
        if ENV["ENABLE_EMAIL"] == "YES"         
            if membership.user_id != current_user.id
                subject = 'TEST'
                @recipient_name = membership.user.userName.titleize
                mail(to: membership.user.email, subject: subject)
            end     
        end

    end
end
2

2 Answers

1
votes

I experienced a similar issue where DeviseAsync was not respecting the custom queue that I had configured using Devise::Async.queue = :some_queue.

You should try the following:

  1. Remove config.queue = :default from devise_async.rb. (DeviseAsync will use a :mailer queue by default).
  2. Run sidekiq -q default -q mailer

Your sidekiq worker will now process the Devise emails from the :mailer queue, in addition to any other jobs in the :default queue

0
votes

I had a similar problem handling with devise_async.

The solution that I've found and that works for me was the following:

User.rb

UserMailer.notification_email(user, team, membership).deliver_later

I've replaced with:

UserMailer.delay.notification_email(user, team, membership)

So, I believe now you can run: bundle exec sidekiq

I hope it helps you