【问题标题】:Background mailing through sidekiq and devise-async, queue fills up but mails aren't processed通过 sidekiq 和 devise-async 发送后台邮件,队列已满但邮件未处理
【发布时间】:2012-11-07 06:28:30
【问题描述】:

我目前正在构建一个 Rails 平台,并且我已经使用 devise 进行身份验证,现在想使用 sidekiq 将默认的 devise 电子邮件移动到后台进程中。我为此使用了 devise-async 并做了以下事情:

添加了 devise_async.rb 文件:

#config/initializers/devise_async.rb
Devise::Async.backend = :sidekiq

在设计模型中添加了异步命令:

#user.rb
devise :database_authenticatable, :async #etc.

宝石的版本如下:

Devise 2.1.2
Devise-async 0.4.0
Sidekiq 2.5.3

我遇到的问题是电子邮件在 sidekiq 队列中传递,但工作人员从不执行发送电子邮件。我也看过devise async not working with sidekiq,他似乎也有同样的问题。但我认为我对 hostname 命令没有问题。

对这个问题有什么想法吗?

【问题讨论】:

  • 问起来可能很愚蠢,但是您是否有一个单独的工作进程通过bundle exec sidekiq -C config.yaml 或类似的方式运行?
  • 问这个问题其实并不愚蠢,因为我认为这样的事情一直都在发生。我实际上使用redis-server 启动了redis,然后使用bundle exec sidekiq 启动了sidekiq。问题是我知道 sidekiq 正在工作,因为我还在后台进程中发送邮件以获取邀请,这与设计是分开的。
  • 试试bundle exec sidekiq -q mailer 我认为设计异步使用邮件队列不是默认的。
  • 非常感谢 :) 它实际上解决了这个问题。我猜 sidekiq 默认只服务于它的 default 队列,所以你必须告诉 sidekiq 使用 mailer 队列。我一定会把它传递给 devise-async 模块,以便他们可以将它包含在他们的文档中!

标签: ruby-on-rails-3 devise sidekiq


【解决方案1】:

答案很简单。你只需要告诉sidekiq 使用mailer 队列,通过bundle exec sidekiq -q mailer 启动sidekiq。这样邮件队列将被处理,没有选项 sidekiq 将仅依赖default 队列。

【讨论】:

  • 两者你都可以使用bundle exec sidekiq -q mailer -q default 注意,这也会使邮件队列优先于默认队列。
【解决方案2】:

在 2019 年,由于 device-async 不是最新的,如果您已完成 ActiveJob 和 sidekiq 设置documentation here。最简单的解决方案是覆盖您的设备 send_devise_notification 与交易邮件有关的实例方法,如here所示

class User < ApplicationRecord
  # whatever association you have here
  devise :database_authenticatable, :confirmable
  after_commit :send_pending_devise_notifications
  # whatever methods you have here

 protected
  def send_devise_notification(notification, *args)
    if new_record? || changed?
      pending_devise_notifications << [notification, args]
    else
      render_and_send_devise_message(notification, *args)
    end
  end

  private

  def send_pending_devise_notifications
    pending_devise_notifications.each do |notification, args|
      render_and_send_devise_message(notification, *args)
    end

    pending_devise_notifications.clear
  end

  def pending_devise_notifications
    @pending_devise_notifications ||= []
  end

  def render_and_send_devise_message(notification, *args)
    message = devise_mailer.send(notification, self, *args)

    # Deliver later with Active Job's `deliver_later`
    if message.respond_to?(:deliver_later)
      message.deliver_later
    # Remove once we move to Rails 4.2+ only, as `deliver` is deprecated.
    elsif message.respond_to?(:deliver_now)
      message.deliver_now
    else
      message.deliver
    end
  end

end

【讨论】:

    【解决方案3】:

    Devise 现在支持此功能 https://github.com/heartcombo/devise#activejob-integration

    class User < ApplicationRecord
    
      devise ...
    
      # Override devise: send emails in the background
      def send_devise_notification(notification, *args)
        devise_mailer.send(notification, self, *args).deliver_later
      end
    
    end
    

    【讨论】:

      猜你喜欢
      • 2014-08-04
      • 2019-07-17
      • 2014-07-18
      • 2016-08-11
      • 2016-11-18
      • 2015-10-15
      • 2011-11-20
      • 2023-04-04
      • 1970-01-01
      相关资源
      最近更新 更多