实际结果:
我们收到的失败邮件工作显示在sidekiq web UI(使用sidekiq-failures gem),大约一分钟后成功重试。
失败错误:
ActiveRecord::RecordNotFound: Couldn't find User with 'id'=234
预期:
我们希望sidekiq工作人员能够立即成功而不会失败,并且稍后会(尽管已成功)重试。
设置:Heroku Cedar-14,Rails 4.2,Puma 2.11.2,Sidekiq 3.3.4,Sidekiq-failures 0.4.4
配置/初始化/ sidekiq.rb:
Sidekiq.configure_server do |config|
database_url = ENV['DATABASE_URL']
if database_url
ENV['DATABASE_URL'] = "#{database_url}?pool=15"
ActiveRecord::Base.establish_connection
end
end
配置/ puma.rb:
workers Integer(ENV['WEB_CONCURRENCY'] || 2)
threads_count = Integer(ENV['MAX_THREADS'] || 5)
threads threads_count, threads_count
preload_app!
rackup DefaultRackup
port ENV['PORT'] || 3000
environment ENV['RACK_ENV'] || 'development'
on_worker_boot do
ActiveRecord::Base.establish_connection
end
配置/ sidekiq.yml
---
:concurrency: 25
:queues:
- default
- mailers
- [low, 1]
- [med, 2]
- [high, 3]
电子邮件是通过控制器操作中的服务运行触发的:
应用/服务/ user_events.rb
@user = User.find(234)
UserMailer.send_email(@user.id).deliver_later
应用/邮寄者/ user_mailer.rb
def send_email(user_id)
@user = User.find(user_id)
# mandrill_headers
headers['X-MC-Track'] = "opens, clicks_all"
headers['X-MC-Tags'] = ['user-event']
mail(to: @user.email, subject: "Hi", css: ["email"])
end
答案 0 :(得分:2)
@user
是新创建的记录吗?如果是这样,我的预感是您在提交当前数据库事务之前将sidekiq电子邮件作业排入队列。
在这种情况下,新用户存在于您的Rails事务中,但连接到数据库的其他进程尚未看到它,因为新用户记录尚未提交到数据库。当sidekiq运行电子邮件作业(它在与Rails应用程序不同的进程中运行)时,它会尝试加载用户并获得RecordNotFound
。
解决方案是将sidekiq作业排在之后(之后)数据库事务。如果您使用ActiveRecord回调,则表示您应使用after_commit
而不是after_create
。
来自sidekiq FAQ:https://github.com/mperham/sidekiq/wiki/FAQ#why-am-i-seeing-a-lot-of-cant-find-modelname-with-id12345-errors-with-sidekiq
答案 1 :(得分:0)
问题解决了。事实证明,heroku回滚还原了一个环境变量。