我有一个Rails Web应用程序,并且将sidekiq与backgroud流程集成在一起。基本集成工作正常。
关键是我需要循环不断地运行后台进程。根据另一篇文章,我创建了一个循环,该循环在初始化程序中触发了工作程序。代码:
sidekiq.rb
Thread.new do
loop do
puts "Sidekiq.Initializer-->before perform worker"
MyWorker.perform_async()
puts "Sidekiq.Initializer-->after perform worker and before sleep"
sleep(1.minutes)
puts "Sidekiq.Initializer-->after sleep"
end
end
但是,此初始化程序运行了两次。首先是启动Rails服务器,然后是sidekiq服务器启动。如何使此功能仅运行一次。
听起来像您对加载顺序有些陌生,但是通常的模式是将其包装在方法中,然后如果希望在Rails开始时调用它,请从初始化程序中调用该方法。我认为Sidekiq服务器那时将无法运行它。
最明显和理想的方法是将值写入数据库,并在执行之前检查它是否存在于工作进程中。
这些可能不会像您需要的那样扩展,但是由于我不了解您的体系结构,因此我会给您一些线索,以便您可以探索自己的道路:
内部config/application.rb
:
def ran_special_job?
@ran_special_job < 5.minutes.ago
end
def ran_special_job_at=(val)
@ran_special_job = val
end
在您的工作中,将其短路:
def perform
return if Rails.application.ran_special_job?
Rails.application.ran_special_job_at = Time.now
puts "I am running"
end
另一种方式,您的工人:
def perform
return if Rails.application.ran_special_job?
Rails.application.ran_special_job!
puts "I am running"
end
以及您的config/application.rb
def ran_special_job?
return false unless File.exists?("special_job.txt")
DateTime.parse(File.read("special_job.txt")) < 5.minutes.ago
end
def ran_special_job!
File.open("special_job.txt", "w") { |file| file.write Time.now }
end
如果您使用的是Heroku或其他不提供持久文件系统的服务,但是您明白了,此方法并不理想。