2

I have next code:

# Gemfile
gem 'sneakers'

# application.rb
config.active_job.queue_adapter = :sneakers

# application_mailer.rb
class ApplicationMailer < ActionMailer::Base
...
  def send_letter(params={})
    mail(params)
  ...
  end
end

# my_mailer_controller.rb
def send_my_mail
  ApplicationMailer.send_letter(params).deliver_later
end

rabbitmq-server is installed and started. When I run 'send_my_mail' function I receive in Rails console message:

[ActiveJob] Enqueued ActionMailer::DeliveryJob (Job ID: b2c66a30-70d1-4bba-a88e-d6260443347d) to Sneakers(mailers) with arguments: "ApplicationMailer", "send_letter", "deliver_now", ...

But when I run ActiveJob worker using terminal command:

WORKERS=ActiveJob::QueueAdapters::SneakersAdapter::JobWrapper rake sneakers:run

nothing happens. Looks like the mailer listener with correct class name does not start so the letters are not sent. In Rabbitmq UI tracer I see record for message event:

Node:         rabbit@ubuntu-trusty-64
Connection:   127.0.0.1:35834 -> 127.0.0.1:5672
Virtual host: /
User:         guest
Channel:      1
Exchange:     sneakers
Routing keys: [<<"mailers">>]
Routed queues: []
Properties:   [{<<"priority">>,signedint,0},
               {<<"delivery_mode">>,signedint,2},
               {<<"content_type">>,longstr,<<"application/octet-stream">>}]
Payload: 
{"job_class":"ActionMailer::DeliveryJob","job_id":"7a58ab27-d110-4e8b-911b-fe821735e1b7","queue_name":"mailers","arguments":["ApplicationMailer","send_newsletter","deliver_now",...

What is the correct WORKER name for 'deliver_later' Active Job and Sneakers? Thank you.

retgoat
  • 2,414
  • 1
  • 16
  • 21
Vadim U
  • 21
  • 2

2 Answers2

3

This happens because ActionMailer uses mailers queue as default queue to send emails. Check this SO question

Sneakers also using mailers queue to send emails by default. But there is no Worker for queue named mailers.

Possible approaches are:

  1. Create a new worker for mailers queue and do all stuff manually
  2. Explicitly define queue in deliver_later method as follows:

    ApplicationMailer.send_letter(params).deliver_later(queue: 'default')
    
  3. Override default queue name for ActionMailer in application.rb

    config.action_mailer.deliver_later_queue_name = 'default'
    

    And send the emails as as usual then:

    ApplicationMailer.send_letter(params).deliver_later
    

Hope this helps

retgoat
  • 2,414
  • 1
  • 16
  • 21
0

This is to elaborate the worker for mailers, as mentioned by retgoat.

Suppose you are delivering later using a specific queue (say, customMailQueue). ApplicationMailer.send_letter(params).deliver_later(queue: 'customMailQueue') The mail would be queued by sneakers in RabbitMQ.

For you to successfully send the queued message, we'll need to consume the message and then execute it.

class YourEmailWorker
    include Sneakers::Worker
    from_queue 'customMailQueue'
    def work(msg)
      job_data = ActiveSupport::JSON.decode(msg)
      ActiveJob::Base.execute job_data
      ack!
    end
  end

Remember, to put the custom Worker on sneaker_worker_group.yml

singleworkergroup:
  classes: YourEmailWorker
  workers: 1

And start the sneakers to start consuming and working on the queued emails.