如何在一段时间后再次运行特定计划任务时可以使用的变量?

时间:2013-08-13 07:14:30

标签: ruby-on-rails ruby rubygems rufus-scheduler

我使用rufus调度程序同时启动了许多预定作业。我想在该代码中有一个变量,该变量只有在一段时间后再次运行时才可用于该预定作业。

如何为每个预定作业维护变量?

1 个答案:

答案 0 :(得分:1)

有多种方法可以做到这一点。我将详细介绍其中一些,从丑陋到某种优雅。

使用rufus-scheduler 2.0.23(https://rubygems.org/gems/rufus-scheduler)在Debian GNU / Linux 7上针对Ruby 1.9.3p392测试了解决方案。

您可以使用全局变量:

require 'rufus-scheduler'

scheduler = Rufus::Scheduler.start_new

scheduler.every '1s' do
  $counter0 ||= 0
  $counter0 += 1
  p [ :c0, $counter0 ]
end
scheduler.every '1s' do
  $counter1 ||= 0
  $counter1 += 1
  p [ :c0, $counter1 ]
end

scheduler.join

或者您可以将作业变量集中在一个全局变量中(注意:这不是线程安全的):

require 'rufus-scheduler'

scheduler = Rufus::Scheduler.start_new

$job_vars = {}

scheduler.every '1s' do |job|
  ($job_vars[job.object_id] ||= {})['counter'] ||= 0
  $job_vars[job.object_id]['counter'] += 1
  p [ job.job_id, job.object_id, $job_vars[job.object_id]['counter'] ]
end
scheduler.every '1.5s' do |job|
  ($job_vars[job.object_id] ||= {})['counter'] ||= 0
  $job_vars[job.object_id]['counter'] += 1
  p [ job.job_id, job.object_id, $job_vars[job.object_id]['counter'] ]
end

scheduler.join

更进一步,只是为了好玩(但仍然不是线程安全的):

require 'rufus-scheduler'

scheduler = Rufus::Scheduler.start_new

$job_vars = {}
job = lambda { |job|
  ($job_vars[job.object_id] ||= {})['counter'] ||= 0
  $job_vars[job.object_id]['counter'] += 1
  p [ job.job_id, job.object_id, $job_vars[job.object_id]['counter'] ]
}

scheduler.every '1s', &job
scheduler.every '1.5s', &job

scheduler.join

最后,您可以在Job类中添加#vars:

require 'rufus-scheduler'

class Rufus::Scheduler::Job
  def vars
    @vars ||= {}
  end
end

scheduler = Rufus::Scheduler.start_new

scheduler.every '1s' do |job|
  job.vars['counter'] = (job.vars['counter'] || 0) + 1
  p [ job.job_id, job.object_id, job.vars['counter'] ]
end
scheduler.every '1.5s' do |job|
  job.vars['counter'] = (job.vars['counter'] || 0) + 1
  p [ job.job_id, job.object_id, job.vars['counter'] ]
end

scheduler.join

这是我更喜欢的解决方案。我打算在rufus-scheduler 3.0(https://github.com/jmettraux/rufus-scheduler)中为Job添加一个类似的变量包。

您也可以将变量放在其他位置并使用job_id / job.object_id作为检索它的键(如第一段代码所做的那样)。

我希望这会有所帮助。