lib/openwfe/util/scheduler.rb in openwferu-0.9.10.653 vs lib/openwfe/util/scheduler.rb in openwferu-0.9.11
- old
+ new
@@ -79,14 +79,20 @@
# end
# end
#
# regenerator = Regenerator.new
#
- # scheduler.schedule_in("4d", regenerator, :monthly)
+ # scheduler.schedule_in("4d", regenerator)
# #
- # # will regenerate the monthly report in four days
+ # # will regenerate the report in four days
#
+ # scheduler.schedule_in(
+ # "5d",
+ # { :schedulable => regenerator, :scope => :month })
+ # #
+ # # will regenerate the monthly report in 5 days
+ #
# There is also schedule_every() :
#
# scheduler.schedule_every("1h20m") do
# regenerate_latest_report()
# end
@@ -176,26 +182,28 @@
#
# Schedules a job by specifying at which time it should trigger.
# Returns the a job_id that can be used to unschedule the job.
#
- def schedule_at (at, schedulable=nil, params=nil, &block)
+ def schedule_at (at, params={}, &block)
- sschedule_at(false, at, nil, schedulable, params, &block)
+ params = prepare_params(params)
+
+ sschedule_at(at, params, &block)
end
#
# Schedules a job by stating in how much time it should trigger.
# Returns the a job_id that can be used to unschedule the job.
#
- def schedule_in (duration, schedulable=nil, params=nil, &block)
+ def schedule_in (duration, params={}, &block)
duration = duration_to_f(duration)
+ params = prepare_params(params)
- return schedule_at(
- Time.new.to_f + duration, schedulable, params, &block)
+ schedule_at(Time.new.to_f + duration, params, &block)
end
#
# Schedules a job in a loop. After an execution, it will not execute
# before the time specified in 'freq'.
@@ -208,13 +216,33 @@
# Thread.new do
# do_the_job()
# end
# end
#
- def schedule_every (freq, schedulable=nil, params=nil, &block)
+ def schedule_every (freq, params={}, &block)
- sschedule_every(freq, nil, schedulable, params, &block)
+ f = duration_to_f freq
+
+ params = prepare_params params
+ schedulable = params[:schedulable]
+ params[:every] = true
+
+ sschedule_at Time.new.to_f + f, params do |job_id, at|
+
+ params[:job_id] = job_id
+
+ if schedulable
+ schedulable.trigger(params)
+ else
+ block.call job_id, at
+ end
+
+ schedule_every(f, params, &block) \
+ unless @dont_reschedule_every
+
+ job_id
+ end
end
#
# Unschedules an 'at' or a 'cron' job identified by the id
# it was given at schedule time.
@@ -222,79 +250,76 @@
def unschedule (job_id)
synchronize do
for i in 0...@pending_jobs.length
if @pending_jobs[i].eid == job_id
- @pending_jobs.delete_at(i)
+ @pending_jobs.delete_at i
return true
end
end
- return true if unschedule_cron_job(job_id)
-
- return false
+ unschedule_cron_job job_id
end
end
#
# Unschedules a cron job
#
def unschedule_cron_job (job_id)
synchronize do
if @cron_entries.has_key?(job_id)
- @cron_entries.delete(job_id)
+ @cron_entries.delete job_id
return true
end
- return false
+ false
end
end
#
# Schedules a cron job, the 'cron_line' is a string
# following the Unix cron standard (see "man 5 crontab" in your command
# line).
#
# For example :
#
- # scheduler.schedule("5 0 * * *", nil, s, p)
- # # will trigger the schedulable s with params p every day
+ # scheduler.schedule("5 0 * * *", s)
+ # # will trigger the schedulable s every day
# # five minutes after midnight
#
- # scheduler.schedule("15 14 1 * *", nil, s, p)
+ # scheduler.schedule("15 14 1 * *", s)
# # will trigger s at 14:15 on the first of every month
#
# scheduler.schedule("0 22 * * 1-5") do
# puts "it's break time..."
# end
# # outputs a message every weekday at 10pm
#
# Returns the job id attributed to this 'cron job', this id can
# be used to unschedule the job.
#
- def schedule (
- cron_line, cron_id=nil, schedulable=nil, params=nil, &block)
+ def schedule (cron_line, params={}, &block)
synchronize do
+
+ params = prepare_params(params)
#
# is a job with the same id already scheduled ?
- if cron_id and unschedule(cron_id)
- ldebug do
- "schedule() unscheduled previous job "+
- "under same name '#{cron_id}'"
- end
- end
+ cron_id = params[:cron_id]
+ cron_id = params[:job_id] unless cron_id
+ unschedule(cron_id) if cron_id
+
#
# schedule
- b = to_block(schedulable, params, &block)
+ b = to_block(params, &block)
entry = CronEntry.new(cron_id, cron_line, &b)
@cron_entries[entry.eid] = entry
- return entry.eid
+ entry.eid
end
end
#
# Returns the job corresponding to job_id, an instance of AtEntry
@@ -303,15 +328,13 @@
def get_job (job_id)
entry = @cron_entries[job_id]
return entry if entry
- @pending_jobs.each do |entry|
- return entry if entry.eid == job_id
+ @pending_jobs.find do |entry|
+ entry.eid == job_id
end
-
- return nil
end
#
# Finds a job (via get_job()) and then returns the wrapped
# schedulable if any.
@@ -321,11 +344,12 @@
return nil unless job_id
j = get_job(job_id)
return j.schedulable if j.respond_to? :schedulable
- return nil
+
+ nil
end
#
# Returns the number of currently pending jobs in this scheduler
# ('at' jobs and 'every' jobs).
@@ -357,39 +381,54 @@
#
# Returns true if the given string seems to be a cron string.
#
def Scheduler.is_cron_string (s)
- return s.match(".+ .+ .+ .+ .+")
+ s.match(".+ .+ .+ .+ .+")
end
protected
- def sschedule_at (
- is_every, at, at_id, schedulable=nil, params=nil, &block)
+ #
+ # Making sure that params is a Hash.
+ #
+ def prepare_params (params)
+ params = { :schedulable => params } \
+ if params.is_a?(Schedulable)
+ params
+ end
+ def sschedule_at (at, params={}, &block)
+
synchronize do
#puts "0 at is '#{at.to_s}' (#{at.class})"
at = OpenWFE::to_ruby_time(at) \
- if at.kind_of? String
+ if at.kind_of?(String)
at = OpenWFE::to_gm_time(at) \
- if at.kind_of? DateTime
+ if at.kind_of?(DateTime)
at = at.to_f \
- if at.kind_of? Time
+ if at.kind_of?(Time)
#puts "1 at is '#{at.to_s}' (#{at.class})"}"
- jobClass = AtEntry
- jobClass = EveryEntry if is_every
+ jobClass = if params[:every]
+ EveryEntry
+ else
+ AtEntry
+ end
- b = to_block(schedulable, params, &block)
- job = jobClass.new(at, at_id, &b)
+ job_id = params[:job_id]
+ b = to_block(params, &block)
+ job = jobClass.new(at, job_id, &b)
+
+ unschedule(job_id) if job_id
+
if at < (Time.new.to_f + @precision)
job.trigger()
return nil
end
@@ -406,59 +445,50 @@
if at <= @pending_jobs[i].at
return push(job, i)
end
end
- return push(job)
+ push(job)
end
end
- def sschedule_every (freq, at_id, schedulable, params, &block)
-
- f = duration_to_f(freq)
-
- job_id = sschedule_at(
- true, Time.new.to_f + f, at_id) do |eid, at|
-
- if schedulable
- schedulable.trigger(params)
- else
- block.call eid, at
- end
-
- sschedule_every(f, eid, schedulable, params, &block) \
- unless @dont_reschedule_every
- end
-
- job_id
- end
-
#
# Ensures that a duration is a expressed as a Float instance.
#
# duration_to_f("10s")
#
# will yields 10.0
#
def duration_to_f (s)
return s if s.kind_of? Float
return OpenWFE::parse_time_string(s) if s.kind_of? String
- return Float(s.to_s)
+ Float(s.to_s)
end
- def to_block (schedulable, params, &block)
- if schedulable
- l = lambda do
- schedulable.trigger(params)
- end
- class << l
- attr_accessor :schedulable
- end
- l.schedulable = schedulable
- l
- else
- block
+ #
+ # Returns a block. If a block is passed, will return it, else,
+ # if a :schedulable is set in the params, will return a block
+ # wrapping a call to it.
+ #
+ def to_block (params, &block)
+
+ return block if block
+
+ schedulable = params[:schedulable]
+
+ return nil unless schedulable
+
+ params.delete :schedulable
+
+ l = lambda do
+ schedulable.trigger(params)
end
+ class << l
+ attr_accessor :schedulable
+ end
+ l.schedulable = schedulable
+
+ l
end
#
# Pushes an 'at' job into the pending job list
#