在 Heroku 上使用 Resque 的后台作业

inf*_*bot 6 ruby-on-rails heroku resque

我在 Heroku 上遇到了一个非常奇怪的问题,我一直在努力解决这个问题。

我的应用程序有一些外部 API 调用和邮件程序,我已将 ActiveJob 设置为在后台运行。在 Heroku 上,我有两个工作人员设置为,并且我按照以下代码段使用 Resque/Redis 组合来处理工作。我在 Heroku 上使用 Redis Cloud 插件。

配置/设置

配置文件

web: bundle exec puma -C config/puma.rb
resque: env TERM_CHILD=1 QUEUE=* bundle exec rake resque:work
Run Code Online (Sandbox Code Playgroud)

库/任务/resque.rake

require "resque/tasks"
require "resque/scheduler/tasks"

task "resque:setup": :environment do
  Resque.before_fork = proc { ActiveRecord::Base.connection.disconnect! }
  Resque.after_fork = proc { ActiveRecord::Base.establish_connection }
end
Run Code Online (Sandbox Code Playgroud)

配置/初始化程序/active_job.rb

Rails.application.config.active_job.queue_adapter = :resque
Run Code Online (Sandbox Code Playgroud)

配置/初始化程序/redis.rb

if ENV["REDISCLOUD_URL"]
  $redis = Redis.new(url: ENV["REDISCLOUD_URL"])
end
Run Code Online (Sandbox Code Playgroud)

配置/初始化程序/resque.rb

if Rails.env.production?
  uri = URI.parse ENV["REDISCLOUD_URL"]
  Resque.redis = Redis.new(host: uri.host, port: uri.port,
                           password: uri.password)
else
  Resque.redis = "localhost:6379"
end
Run Code Online (Sandbox Code Playgroud)

问题

我遇到的问题是,当用户在浏览器中使用该应用程序(即,与 Web 工作者交互)并执行触发 ActiveJob 作业之一的操作时,该作业使用web工作者而非resque工作者“内联”运行。当我在 Heroku 应用程序控制台(通过运行打开heroku run rails console)中运行将作业排队的特定模型方法时,它会将作业添加到 Redis 并按resque预期使用工作程序运行它。

为什么一种方式可以正常工作而另一种方式不起作用?我已经查看了关于该主题的几乎所有教程/SO 问题,并尝试了所有方法,因此任何帮助都可以运行作业,但正确的工人会很棒!

提前致谢!

inf*_*bot 5

我设法通过使用我的配置来解决这个问题。似乎动作是通过 ActiveJob 的“内联”默认值而不是通过 Resque 进行隧道传输的。为了让事情正常工作,我只需要直接Resque.redis等于设置的$redis变量,config/initializers/redis.rb所以一切都指向同一个 Redis 实例,然后将配置集移动config/initializers/active_job.rbapplication.rb.

作为参考,所有工作的新的和改进的配置是:

配置/设置

配置文件

web: bundle exec puma -C config/puma.rb
resque: env TERM_CHILD=1 RESQUE_TERM_TIMEOUT=7 QUEUE=* bundle exec rake resque:work
Run Code Online (Sandbox Code Playgroud)

库/任务/resque.rake

require "resque/tasks"

task "resque:setup" => :environment
Run Code Online (Sandbox Code Playgroud)

配置/应用程序.rb

module App
  class Application < Rails::Application
    ...

    # Set Resque as ActiveJob queue adapter.
    config.active_job.queue_adapter = :resque
  end
end
Run Code Online (Sandbox Code Playgroud)

配置/初始化程序/redis.rb

if ENV["REDISCLOUD_URL"]
  $redis = Redis.new(url: ENV["REDISCLOUD_URL"])
end
Run Code Online (Sandbox Code Playgroud)

配置/初始化程序/resque.rb

Resque.redis = Rails.env.production? ? $redis : "localhost:6379"
Run Code Online (Sandbox Code Playgroud)