Max*_*nce 3 ruby-on-rails sidekiq ruby-on-rails-5
在我的应用程序中,我尝试按顺序执行两个工作任务。首先,使用 Wicked pdf 创建 PDF,然后在创建 PDF 后,将附有 PDF 的电子邮件发送给两个不同的收件人。
这就是控制器中的调用:
PdfWorker.perform_async(@d.id)
MailingWorker.perform_in(1.minutes, @d.id,@d.class.name.to_s)
Run Code Online (Sandbox Code Playgroud)
第一个工作人员创建 PDF,第二个工作人员发送电子邮件。
这是第二个工人:
class MailingWorker
include Sidekiq::Worker
sidekiq_options retry: false
def perform(d_id,model)
@d = eval(model).find(d_id)
@model = model
if @d.pdf.present?
ProfessionnelMailer.notification_d(@d).deliver
ClientMailer.notification_d(@d).deliver
else
MailingWorker.perform_in(1.minutes, @d.id, @model.to_s)
end
end
end
Run Code Online (Sandbox Code Playgroud)
if 语句检查 PDF 是否已创建。如果确实发送了两封邮件,否则,一分钟后再次调用同一工作人员,只是为了让 Heroku 服务器有额外的时间来处理 PDF 创建,以防需要更多时间或排很长的队列。
但如果 PDF 确实处理失败,上面的结果就会陷入无限循环。
有没有办法来解决这个问题 ?
我看到的一种选择是调用 PDF 创建工作人员内部的第二个工作人员,尽管我真的不想将工作人员嵌套得太深。将它们分开使我的控制器更加清晰,我可以看到操作的顺序。但欢迎任何建议。
另一种选择是使用sidekiq_options retry: 5并请求控制器重试,该重试可计入总共 5 次重试,而不是重试工作人员,else MailingWorker.perform_in(1.minutes, @d.id, @model.to_s)但我不知道如何执行此操作。根据此线程https://github.com/mperham/sidekiq/issues/769它将引发异常,但我不确定如何执行此操作...(我也不确定重试将等待多长时间在使用异常方法处理之前,通过上面的解决方案我可以控制时间范围..)
小智 6
如果您不希望有嵌套的工作人员,则不要MailingWorker再次将其排队,而是在 PDF 不存在时引发异常。另外,配置worker重试选项,以便sidekiq将其推送到重试队列并在某个时间再次运行它。根据文档,
Sidekiq will retry failures with an exponential backoff using the
formula (retry_count ** 4) + 15 + (rand(30) * (retry_count + 1)) (i.e.
15, 16, 31, 96, 271, ... seconds + a random amount of time). It will
perform 25 retries over approximately 21 days.
Run Code Online (Sandbox Code Playgroud)
工作人员代码将更像是,
class MailingWorker
include Sidekiq::Worker
sidekiq_options retry: 5
def perform(d_id,model)
@d = eval(model).find(d_id)
@model = model
if @d.pdf.present?
ProfessionnelMailer.notification_d(@d).deliver
ClientMailer.notification_d(@d).deliver
else
raise "PDF not present"
end
end
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12290 次 |
| 最近记录: |