1

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 = 'test@gmail.com'
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: "test@gmail.com"

    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
Kyle Bachan
  • 1,053
  • 2
  • 15
  • 33

2 Answers2

1

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

Ian
  • 509
  • 3
  • 6
  • I actually had been launching sidekiq with bundle exec sidekiq -C config/sidekiq.yml -q mailer. It seemed to start working as soon as I removed -q mailer. Not sure why though. – Kyle Bachan Mar 13 '15 at 21:04
  • When you run `sidekiq -q mailer` it will run all the jobs in the "mailer" queue. If you omit the `-q mailer`, then sidekiq will run jobs from the "default" queue. If you want to run both queues, you could run `sidekiq -q default -q mailer` – Ian Mar 16 '15 at 17:18
0

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

André
  • 71
  • 2