Throttling mail sending with SolidQueue not working

Hi all,

I’m trying to throttle mail sending to 1 mail per 3 seconds using SolidQueue.

I set up the queue like this in queue.yml:

default: &default
  dispatchers:
    - polling_interval: 1
      batch_size: 500
  workers:
    - queues: screening_mailer
      threads: 1
      processes: 1
      polling_interval: 3
    - queues: [ default, solid_queue_* ]
      threads: 3
      processes: <%= ENV.fetch("JOB_CONCURRENCY", 1) %>
      polling_interval: 0.1

My mailer class looks like:

class ScreeningMailer < ApplicationMailer
  
  self.deliver_later_queue_name = :screening_mailer

  [...]

  def invite
    [...]
    mail(to: 'xxx@xxx.xxx', subject: "...")
  end

end

And called as:

ScreeningMailer.with(screening_form: self).invite.deliver_later

However, when I send a bunch of mails though a script from the production server, the mails are all send instantly (not with 3 second intervals).

Anybody that can shed more light on what I’m doing wrong?

I suspect what’s happening here is that all messages are added to the queue immediately, and that the polling interval only changes how often the queue is polled. Upon polling all pending messages are found and sent in one go. In addition to the polling_interval think you need to restrict concurrency to one job with the same key at a time, see the “concurrency control” section in the documentation: