首页 文章

使用Sidekiq作业的Rails 4.2 ActiveJob失败,然后在Heroku上成功重试

提问于
浏览
0

Actual Result:

我们正在使用sidekiq web UI(使用sidekiq-failures gem)显示失败的邮件工作,这些工作在大约一分钟后成功重试 .

Failure Error:

ActiveRecord::RecordNotFound: Couldn't find User with 'id'=234

Expected:

我们希望sidekiq工作人员能够立即成功并且不会失败,并且稍后会(尽管已成功)重试 .

设置:Heroku Cedar-14,Rails 4.2,Puma 2.11.2,Sidekiq 3.3.4,Sidekiq-failures 0.4.4

config/initializers/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

config/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

config/sidekiq.yml

---
:concurrency: 25
:queues:
  - default
  - mailers
  - [low, 1]
  - [med, 2]
  - [high, 3]

电子邮件是从控制器操作中的服务运行触发的:

app/services/user_events.rb

@user = User.find(234)
UserMailer.send_email(@user.id).deliver_later

app/mailers/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

2 回答

  • 0

    @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

  • 2

    问题解决了 . 事实证明,heroku回滚还原了一个环境变量 .

相关问题