how to have a variable that will available to particular scheduled task whenever it runs again after some time?

StackOverflow https://stackoverflow.com/questions/18202848

質問

I am starting many scheduled jobs at the same time using rufus scheduler. I want a variable in that code that will be available to only that scheduled job, when it runs again after some time.

how can i maintain a variable for for each scheduled job?

役に立ちましたか?

解決

there multiple ways to do that. I'll detail some of those, going from ugly to somehow elegant.

Solutions tested against Ruby 1.9.3p392 on Debian GNU/Linux 7 with rufus-scheduler 2.0.23 (https://rubygems.org/gems/rufus-scheduler).

You could use a global variable:

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

Or you could centralize the job variables in a single global variable (note: this isn't thread-safe):

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

One step further, just for fun (but still not thread-safe):

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

Finally, you could add a #vars to the Job class:

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

This is the solution I prefer. I intend to add a similar bag of variables to Job in rufus-scheduler 3.0 (https://github.com/jmettraux/rufus-scheduler).

You could also put the variable somewhere else and use the job_id / job.object_id as a key to retrieve it (as the first snips of code do).

I hope this will help.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top