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.