lib/rufus/scheduler/scheduler.rb in rufus-scheduler-1.0.13 vs lib/rufus/scheduler/scheduler.rb in rufus-scheduler-1.0.14
- old
+ new
@@ -1,6 +1,5 @@
-#
#--
# Copyright (c) 2006-2009, John Mettraux, jmettraux@gmail.com
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@@ -17,18 +16,14 @@
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
-#++
#
+# Made in Japan.
+#++
-#
-# "made in Japan"
-#
-# John Mettraux at openwfe.org
-#
require 'thread'
require 'rufus/scheduler/otime'
require 'rufus/scheduler/jobs'
require 'rufus/scheduler/cronline'
@@ -337,11 +332,11 @@
# accepts a String value following the "Mdhms" scheme the rufus-scheduler
# uses.
#
class Scheduler
- VERSION = '1.0.13'
+ VERSION = '1.0.14'
#
# By default, the precision is 0.250, with means the scheduler
# will check for jobs to execute 4 times per second.
#
@@ -376,12 +371,14 @@
@pending_jobs = []
@cron_jobs = {}
@non_cron_jobs = {}
- @schedule_queue = Queue.new
- @unschedule_queue = Queue.new
+ # @schedule_queue = Queue.new
+ # @unschedule_queue = Queue.new
+
+ @edit_queue = Queue.new
#
# sync between the step() method and the [un]schedule
# methods is done via these queues, no more mutex
@scheduler_thread = nil
@@ -653,11 +650,12 @@
# schedule
b = to_block(params, &block)
job = CronJob.new(self, cron_id, cron_line, params, &b)
- @schedule_queue << job
+ # @schedule_queue << job
+ @edit_queue << [ :schedule, job ]
job.job_id
end
#
@@ -675,11 +673,11 @@
# Unschedules an 'at' or a 'cron' job identified by the id
# it was given at schedule time.
#
def unschedule (job_id)
- @unschedule_queue << job_id
+ @edit_queue << [ :unschedule, job_id ]
end
#
# Unschedules a cron job
#
@@ -840,18 +838,20 @@
if jobClass == AtJob && job.at < (Time.new.to_f + @precision)
job.trigger() unless params[:discard_past]
- @non_cron_jobs.delete job.job_id # just to be sure
+ # change to @non_cron_jobs must be executed on scheduler thread (in step_schedule)
+ # @non_cron_jobs.delete(job.job_id) # just to be sure
return nil
end
- @non_cron_jobs[job.job_id] = job
+ # change to @non_cron_jobs must be executed on scheduler thread (in step_schedule)
+ # @non_cron_jobs[job.job_id] = job
- @schedule_queue << job
+ @edit_queue << [ :schedule, job ]
job.job_id
end
#
@@ -922,57 +922,62 @@
# determine if there are jobs to trigger else to get back to sleep.
# 'cron' jobs get executed if necessary then 'at' jobs.
#
def step
- step_unschedule
- # unschedules any job in the unschedule queue before
- # they have a chance to get triggered.
+ step_edit
+ # handle ops in the edit_queue
+ # this ensures that schedule and unschedule requests are processed
+ # in order
step_trigger
# triggers eligible jobs
- step_schedule
- # schedule new jobs
-
# done.
end
#
- # unschedules jobs in the unschedule_queue
+ # schedules or unschedules job in the edit_queue
+ # schedule's and unschedule are processed in order
#
- def step_unschedule
-
+ def step_edit
loop do
+ break if @edit_queue.empty?
+ op, j = @edit_queue.pop
- break if @unschedule_queue.empty?
+ case op
+ when :schedule
+ if j.is_a?(CronJob)
- do_unschedule(@unschedule_queue.pop)
- end
- end
+ @cron_jobs[j.job_id] = j
- #
- # adds every job waiting in the @schedule_queue to
- # either @pending_jobs or @cron_jobs.
- #
- def step_schedule
+ else # it's an 'at' job
- loop do
+ # add job to @non_cron_jobs
+ @non_cron_jobs[j.job_id] = j
+ push_pending_job j
- break if @schedule_queue.empty?
-
- j = @schedule_queue.pop
-
- if j.is_a?(CronJob)
-
- @cron_jobs[j.job_id] = j
-
- else # it's an 'at' job
-
- push_pending_job j
+ end
+ when :unschedule
+ do_unschedule(j)
+ else
+ raise ArgumentError
end
end
end
+
+ #
+ # unschedules jobs in the unschedule_queue
+ #
+ # def step_unschedule
+ #
+ # loop do
+ #
+ # break if @unschedule_queue.empty?
+ #
+ # do_unschedule(@unschedule_queue.pop)
+ # end
+ # end
#
# triggers every eligible pending (at or every) jobs, then every eligible
# cron jobs.
#