lib/openwfe/util/scheduler.rb in openwferu-0.9.12 vs lib/openwfe/util/scheduler.rb in openwferu-0.9.12.863
- old
+ new
@@ -102,43 +102,66 @@
# Use with care though, if you create a scheduler, set this attribute
# to true and start the scheduler, the scheduler will immediately exit.
# This attribute is best used indirectly : the method
# join_until_no_more_jobs() wraps it.
#
+ # Since OpenWFEru 0.9.13, the :scheduler_precision can be set when
+ # instantiating the scheduler.
+ #
+ # scheduler = OpenWFE::Scheduler.new(:scheduler_precision => 0.500)
+ # scheduler.start
+ # #
+ # # instatiates a scheduler that checks its jobs twice per second
+ # # (the default is 4 times per second (0.250))
+ #
class Scheduler
include MonitorMixin
- attr_accessor \
- :precision,
- :exit_when_no_more_jobs
+ #
+ # By default, the precision is 0.250, with means the scheduler
+ # will check for jobs to execute 4 times per second.
+ #
+ attr_accessor :precision
- def initialize
+ #
+ # As its name implies.
+ #
+ attr_accessor :stopped
+
+ def initialize (params={})
+
super()
@pending_jobs = []
@cron_entries = {}
@scheduler_thread = nil
@precision = 0.250
- #
- # every 250ms, the scheduler wakes up
+ # every 250ms, the scheduler wakes up (default value)
+ begin
+ @precision = Float(params[:scheduler_precision])
+ rescue Exception => e
+ # let precision at its default value
+ end
@exit_when_no_more_jobs = false
@dont_reschedule_every = false
@last_cron_minute = -1
- @stopped = false
+ @stopped = true
end
#
# Starts this scheduler (or restart it if it was previously stopped)
#
def sstart
+ @stopped = false
+
@scheduler_thread = Thread.new do
if defined?(JRUBY_VERSION)
require 'java'
java.lang.Thread.current_thread.name = "openwferu scheduler (Ruby Thread)"
@@ -187,10 +210,25 @@
#
# Schedules a job by specifying at which time it should trigger.
# Returns the a job_id that can be used to unschedule the job.
#
+ # This method returns a job identifier which can be used to unschedule()
+ # the job.
+ #
+ # If the job is specified in the past, it will be triggered immediately
+ # but not scheduled.
+ # To avoid the triggering, the parameter :discard_past may be set to
+ # true :
+ #
+ # jobid = scheduler.schedule_at(yesterday, :discard_past => true) do
+ # puts "you'll never read this message"
+ # end
+ #
+ # And 'jobid' will hold a nil (not scheduled).
+ #
+ #
def schedule_at (at, params={}, &block)
params = prepare_params(params)
sschedule_at(at, params, &block)
@@ -199,10 +237,13 @@
#
# 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.
#
+ # This method returns a job identifier which can be used to unschedule()
+ # the job.
+ #
def schedule_in (duration, params={}, &block)
duration = duration_to_f(duration)
params = prepare_params(params)
@@ -221,10 +262,13 @@
# Thread.new do
# do_the_job()
# end
# end
#
+ # This method returns a job identifier which can be used to unschedule()
+ # the job.
+ #
def schedule_every (freq, params={}, &block)
f = duration_to_f freq
params = prepare_params params
@@ -280,11 +324,11 @@
end
#
# Schedules a cron job, the 'cron_line' is a string
# following the Unix cron standard (see "man 5 crontab" in your command
- # line).
+ # line, or http://www.google.com/search?q=man%205%20crontab).
#
# For example :
#
# scheduler.schedule("5 0 * * *", s)
# # will trigger the schedulable s every day
@@ -299,10 +343,13 @@
# # 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.
#
+ # This method returns a job identifier which can be used to unschedule()
+ # the job.
+ #
def schedule (cron_line, params={}, &block)
synchronize do
params = prepare_params(params)
@@ -399,10 +446,14 @@
params = { :schedulable => params } \
if params.is_a?(Schedulable)
params
end
+ #
+ # The core method behind schedule_at and schedule_in (and also
+ # schedule_every). It's protected, don't use it directly.
+ #
def sschedule_at (at, params={}, &block)
synchronize do
#puts "0 at is '#{at.to_s}' (#{at.class})"
@@ -429,10 +480,10 @@
job = jobClass.new(at, job_id, &b)
unschedule(job_id) if job_id
if at < (Time.new.to_f + @precision)
- job.trigger()
+ job.trigger() unless params[:discard_past]
return nil
end
return push(job) \
if @pending_jobs.length < 1