allow overriding periodic jobs schedules

using a new config/periodic_jobs.yml file

test plan: edit config/periodic_jobs.yml, and verify that the overridden
jobs run at that new schedule. add an invalid override, and verify that
`script/delayed_job run` dies immediately.

closes #6875

Change-Id: Ia4611fb6f81fe82feda784300a3adf82e37a53e4
Reviewed-on: https://gerrit.instructure.com/8262
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: Cody Cutrer <cody@instructure.com>
This commit is contained in:
Brian Palmer 2012-01-24 14:15:11 -07:00
parent f436c8f0d4
commit 51f1d9273b
4 changed files with 53 additions and 1 deletions

View File

@ -0,0 +1,15 @@
# you can override the cron schedule for periodic jobs using this configuration file
#
# the default schedules are in config/periodic_jobs.rb
#
# shifting the time to a different hour is typically fine. changing the
# frequency of the job is more dangerous -- make sure you understand the
# consequences.
development:
# the key is the name of the job, the value is the new cron line
# Reporting::CountsReport.process: "0 6 * * *"
test:
production:

View File

@ -1,5 +1,7 @@
module Delayed
class Periodic
attr_reader :name, :cron
yaml_as "tag:ruby.yaml.org,2002:Delayed::Periodic"
def to_yaml(opts = {})
@ -13,6 +15,15 @@ class Periodic
cattr_accessor :scheduled
self.scheduled = {}
# throws an error if any cron override in config/periodic_jobs.yml is invalid
def self.audit_overrides!
overrides = Setting.from_config('periodic_jobs') || {}
overrides.each do |name, cron_line|
# throws error if the line is malformed
Rufus::CronLine.new(cron_line)
end
end
def self.load_periodic_jobs_config
require Rails.root+'config/periodic_jobs'
@ -26,6 +37,8 @@ class Periodic
def self.cron(job_name, cron_line, job_args = {}, &block)
raise ArgumentError, "job #{job_name} already scheduled!" if self.scheduled[job_name]
override = (Setting.from_config('periodic_jobs') || {})[job_name]
cron_line = override if override
self.scheduled[job_name] = self.new(job_name, cron_line, job_args, block)
end

View File

@ -70,8 +70,8 @@ class Pool
say "Started job master", :info
$0 = "delayed_jobs_pool"
read_config(options[:config_file])
spawn_all_workers
spawn_periodic_auditor
spawn_all_workers
say "Workers spawned"
join
say "Shutting down"
@ -126,6 +126,10 @@ class Pool
def spawn_periodic_auditor
return if @config[:disable_periodic_jobs]
# audit any periodic job overrides for invalid cron lines
# we do this here to fail as early as possible
Delayed::Periodic.audit_overrides!
@periodic_thread = Thread.new do
# schedule the initial audit immediately on startup
schedule_periodic_audit

View File

@ -430,6 +430,26 @@ shared_examples_for 'a backend' do
it "should reject duplicate named jobs" do
proc { Delayed::Periodic.cron('my SimpleJob', '*/15 * * * * *') {} }.should raise_error(ArgumentError)
end
it "should allow overriding schedules using periodic_jobs.yml" do
Setting.set_config('periodic_jobs', { 'my ChangedJob' => '*/10 * * * * *' })
Delayed::Periodic.scheduled = {}
Delayed::Periodic.cron('my ChangedJob', '*/5 * * * * *') do
@backend.enqueue(SimpleJob.new)
end
Delayed::Periodic.scheduled['my ChangedJob'].cron.original.should == '*/10 * * * * *'
Delayed::Periodic.audit_overrides!
end
it "should fail if the override cron line is invalid" do
Setting.set_config('periodic_jobs', { 'my ChangedJob' => '*/10 * * * * * *' }) # extra asterisk
Delayed::Periodic.scheduled = {}
expect { Delayed::Periodic.cron('my ChangedJob', '*/5 * * * * *') do
@backend.enqueue(SimpleJob.new)
end }.to raise_error
expect { Delayed::Periodic.audit_overrides! }.to raise_error
end
end
module InDelayedJobTest