Rails 4 - Mailer deliver_later没有按照我的预期进行操作,阻止了UI

And*_*ers 6 ruby ruby-on-rails actionmailer ruby-on-rails-4

我有一个rails应用程序,其中我有一个发送了很多电子邮件的功能.我想这样做asynchronously,我认为该方法deliver_later会这样做.目前我从用户点击submit到提交表单时有一些延迟- 这会导致糟糕的用户体验(这是一个非常简单的表单).我的实现看起来像这样:

def create

  respond_to do |format|
    if @competition.save
      [...]
      send_notification_to_team_members
    end
end

def send_notification_to_team_members
  @team.members.each do |member|
    unless member.user.eql?(current_user)
      Mailer.deliver_new_competition_notification(member.user,   @competition).deliver_later
    end
  end
end 
Run Code Online (Sandbox Code Playgroud)

目前,该动作需要约4秒钟才能完成.我也尝试过:

Mailer.deliver_new_competition_notification(member.user,  @competition).deliver_later(wait: 1.minute)
Run Code Online (Sandbox Code Playgroud)

然后它需要更长时间 - 我估计约1分钟.

所以,我是deliver_later错误地使用,还是方法没有做我期望的.在那种情况下,我可以使用另一种方法来提高我的表现吗?

Fre*_*ung 15

deliver_later使用ActiveJob提供异步执行.

然而,ActiveJob本身并不提供异步性 - 它是一个统一的api层,可以由许多后端来实现.默认的一个只运行内联它不是异步.

要获得异步使用,您需要选择异步后端.您可以在应用程序的配置中配置后端

 config.active_job.queue_adapter = ...
Run Code Online (Sandbox Code Playgroud)

通常,大多数适配器都需要相应的gem(例如delayed_job,sidekiq,sucker_punch),它们也可能有自己的依赖关系(例如sidekiq要求你使用redis.

  • 比delayed_job更容易?值得一提的是sideqik要求您的代码(和依赖项)是线程安全的.作为一个快乐的媒介,我会推荐resque,因为它比delayed_job快,但不需要sideqik的线程安全. (3认同)