我注意到当Sidekiq / Active Job由于抛出错误而失败时,会回滚作业期间发生的任何数据库更改。这似乎是使工作成为幂等的有意识的特征。
我的问题是,作业运行的方法可以向用户发送电子邮件,并使用数据库修改来防止重新发送电子邮件。如果回滚数据库更改,则只要重试作业,就会重新发送电子邮件。
这大致是我的工作:
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" data-bind="gatedValue: myNumber, gatedValidator: myValidator" />
计划使用sidekiq-scheduler定期运行作业。我使用的是rails-api v5。
我添加了class ProcessPaymentsJob < ApplicationJob
queue_as :default
def perform(*args)
begin
# This can send emails to users.
PaymentProcessor.perform
rescue StandardError => error
puts 'PaymentsJob failed, ignoring'
puts error
end
end
end
以尝试阻止作业回滚数据库更改但仍然会发生。
我想到,也许这不是Sidekiq问题,而是Rails的一个功能。
这是防止用户通过电子邮件发送垃圾邮件的最佳解决方案吗?
答案 0 :(得分:0)
您可以在PaymentProcessor内的事务中包装数据库更改,挽救数据库回滚,并且只有在事务成功时才发送电子邮件。有点像这样:
# ../payment_processor.rb
def perform
ActiveRecord::Base.transaction do
# AllTheThings.save!
end
rescue ActiveRecord::RecordInvalid => exception
# if things fail to save, handle the exception however you like
else
# if no exception is raised, send your email
end
答案 1 :(得分:0)
听起来你的后台工作做得太多了。如果发送电子邮件与作业是否成功无关,则应将工作分成两个工作:一个用于发送电子邮件,另一个用于执行其他处理工作。
或者,您可以使用Sidekiq批处理并使上面的第一个作业依赖于第二个成功执行。
快乐的Sidekiq'ing!