mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-28 18:17:29 -05:00
71a38542a4
BUGFIX: improve scheduler robustness, in case redis is disconnected during operation If sidekiq is terminated while task is running, it will be picked up and ran again New owner on tasks to help debugging better #stop semantics for tests
122 lines
2.5 KiB
Ruby
122 lines
2.5 KiB
Ruby
# encoding: utf-8
|
|
require 'spec_helper'
|
|
require 'scheduler/scheduler'
|
|
|
|
describe Scheduler::Manager do
|
|
|
|
module Testing
|
|
class RandomJob
|
|
extend ::Scheduler::Schedule
|
|
|
|
def self.runs=(val)
|
|
@runs = val
|
|
end
|
|
|
|
def self.runs
|
|
@runs ||= 0
|
|
end
|
|
|
|
every 5.minutes
|
|
|
|
def perform
|
|
self.class.runs+=1
|
|
sleep 0.001
|
|
end
|
|
end
|
|
|
|
class SuperLongJob
|
|
extend ::Scheduler::Schedule
|
|
|
|
every 10.minutes
|
|
|
|
def perform
|
|
sleep 1000
|
|
end
|
|
end
|
|
end
|
|
|
|
let(:manager) { Scheduler::Manager.new(DiscourseRedis.new) }
|
|
|
|
before do
|
|
$redis.del manager.class.lock_key
|
|
$redis.del manager.class.queue_key
|
|
manager.remove(Testing::RandomJob)
|
|
manager.remove(Testing::SuperLongJob)
|
|
end
|
|
|
|
after do
|
|
manager.stop!
|
|
manager.remove(Testing::RandomJob)
|
|
manager.remove(Testing::SuperLongJob)
|
|
end
|
|
|
|
describe '#sync' do
|
|
|
|
it 'increases' do
|
|
Scheduler::Manager.seq.should == Scheduler::Manager.seq - 1
|
|
end
|
|
end
|
|
|
|
describe '#tick' do
|
|
|
|
it 'should recover from crashed manager' do
|
|
|
|
info = manager.schedule_info(Testing::SuperLongJob)
|
|
info.next_run = Time.now.to_i - 1
|
|
info.write!
|
|
|
|
manager.tick
|
|
manager.stop!
|
|
|
|
$redis.del manager.identity_key
|
|
|
|
manager = Scheduler::Manager.new(DiscourseRedis.new)
|
|
manager.reschedule_orphans!
|
|
|
|
info = manager.schedule_info(Testing::SuperLongJob)
|
|
info.next_run.should <= Time.now.to_i
|
|
end
|
|
|
|
it 'should only run pending job once' do
|
|
|
|
Testing::RandomJob.runs = 0
|
|
|
|
info = manager.schedule_info(Testing::RandomJob)
|
|
info.next_run = Time.now.to_i - 1
|
|
info.write!
|
|
|
|
(0..5).map do
|
|
Thread.new do
|
|
manager = Scheduler::Manager.new(DiscourseRedis.new)
|
|
manager.blocking_tick
|
|
manager.stop!
|
|
end
|
|
end.map(&:join)
|
|
|
|
Testing::RandomJob.runs.should == 1
|
|
|
|
info = manager.schedule_info(Testing::RandomJob)
|
|
info.prev_run.should be <= Time.now.to_i
|
|
info.prev_duration.should be > 0
|
|
info.prev_result.should == "OK"
|
|
end
|
|
|
|
end
|
|
|
|
describe '#discover_schedules' do
|
|
it 'Discovers Testing::RandomJob' do
|
|
Scheduler::Manager.discover_schedules.should include(Testing::RandomJob)
|
|
end
|
|
end
|
|
|
|
describe '#next_run' do
|
|
it 'should be within the next 5 mins if it never ran' do
|
|
|
|
manager.remove(Testing::RandomJob)
|
|
manager.ensure_schedule!(Testing::RandomJob)
|
|
|
|
manager.next_run(Testing::RandomJob)
|
|
.should be_within(5.minutes.to_i).of(Time.now.to_i + 5.minutes)
|
|
end
|
|
end
|
|
end
|