I am using Sorcery Gem to Authenticate user in my Rails application. Everything is working fine. When user register then I am able to send user activation email. However sending email is taking long time so I was thinking to delay the email or send email in backgroud using Sidekiq. I read Sorcery documentation but couldn't find the way to delay the email using Sidekiq.
Please guide me how to delay the email send by Sorcery gem using Sidekiq.
CodePudding user response:
There could be two approach to this:
- Call Sidekiq worker inside Mailer
what I understand from the docs is that you can configure it to call any
Mailer. What you could do inside the method is call
MailerJob.perform_late(*arg) instead of calling mail(*args) right away
Assuming you have a code something like this (ref: https://github.com/Sorcery/sorcery/wiki/User-Activation)
# app/mailers/user_mailer.rb
def activation_needed_email(user)
@user = user
@url = activate_user_url(@user.activation_token)
mail(to: user.email, subject: 'Welcome to My Awesome Site')
end
You can change the code to this
# app/mailers/user_mailer.rb
def activation_needed_email(user)
@user = user
@url = activate_user_url(@user.activation_token)
# mail(to: user.email, subject: 'Welcome to My Awesome Site')
MyMailerWorker.perfor_later(to: user.email, subject: 'Welcome to My Awesome Site')
end
Your worker would be defined as per the sidekiq docs(ref: https://github.com/mperham/sidekiq/wiki/Getting-Started)
class MyMailerWorker
include Sidekiq::Worker
def perform(to: nil, subject: nil)
MailerIWantToCall.send_activation_email(to, subject)
end
end
P.S: Option 1 is not a clean approach but works if you are stuck with Sorcery legacy configs
- Don't set mail settings for srcoery(A cleaner approach)
Do not setup mail through sorcery at all.You can revert the changes
mentioned for UserMailer on this page
(github.com/Sorcery/sorcery/wiki/User-Activation) and add a callback on User
model based on when do you want to trigger an email and that way you have
control over what to call and with sidekiq or not.
CodePudding user response:
Use snippet from DelayedJob Integration
module Sorcery module Model module InstanceMethods def generic_send_email(method, mailer) config = sorcery_config mail = config.send(mailer).delay.send(config.send(method), self) end end end end
Add this code to bottom of the file: config/initializers/sorcery.rb.
Add
Sidekiq::Extensions.enable_delay!toconfig/initializers/sidekiq.rb.Add to
config/environments/test.rb.config.active_job.queue_adapter = :sidekiq config.action_mailer.perform_deliveries = true config.action_mailer.raise_delivery_errors = true config.action_mailer.delivery_method = :test config.action_mailer.default_url_options = { :host => 'localhost:3000' }Example of method from
UserMailerfrom User-Activationdef activation_needed_email(user) @user = user @url = activate_user_url(@user.activation_token) mail(to: user.email, subject: 'Activation') endAdd to
spec/rails_helper.rb.require 'sidekiq/testing' Sidekiq::Testing.fake!Write test to check it, must pass.
require 'rails_helper' RSpec.describe UserMailer, type: :mailer do let(:user) { create(:user) } let(:mail) { described_class.activation_needed_email(user) } describe 'activation_needed_email' do it 'creates job in sidekiq' do expect do mail end.to change { Sidekiq::Worker.jobs.size }.by(1) end end end
