mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-30 10:58:31 -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
89 lines
2 KiB
Ruby
89 lines
2 KiB
Ruby
module Scheduler
|
|
class ScheduleInfo
|
|
attr_accessor :next_run,
|
|
:prev_run,
|
|
:prev_duration,
|
|
:prev_result,
|
|
:current_owner
|
|
|
|
def initialize(klass, manager)
|
|
@klass = klass
|
|
@manager = manager
|
|
|
|
key = Manager.schedule_key(klass)
|
|
data = nil
|
|
|
|
if data = $redis.get(key)
|
|
data = JSON.parse(data)
|
|
end
|
|
|
|
if data
|
|
@next_run = data["next_run"]
|
|
@prev_run = data["prev_run"]
|
|
@prev_result = data["prev_result"]
|
|
@prev_duration = data["prev_duration"]
|
|
@current_owner = data["current_owner"]
|
|
end
|
|
rescue
|
|
# corrupt redis
|
|
@next_run = @prev_run = @prev_result = @prev_duration = @current_owner = nil
|
|
end
|
|
|
|
def valid?
|
|
return false unless @next_run
|
|
(!@prev_run && @next_run < Time.now.to_i + 5.minutes) ||
|
|
( @prev_run &&
|
|
@prev_run <= Time.now.to_i &&
|
|
@next_run < @prev_run + @klass.every * (1 + @manager.random_ratio)
|
|
)
|
|
end
|
|
|
|
def schedule!
|
|
if !valid? && @prev_run
|
|
mixup = @klass.every * @manager.random_ratio
|
|
mixup = (mixup * Random.rand - mixup / 2).to_i
|
|
@next_run = @prev_run + mixup + @klass.every
|
|
end
|
|
|
|
if !valid?
|
|
@next_run = Time.now.to_i + 5.minutes * Random.rand
|
|
end
|
|
|
|
write!
|
|
end
|
|
|
|
def write!
|
|
key = Manager.schedule_key(@klass)
|
|
clear!
|
|
redis.set key, {
|
|
next_run: @next_run,
|
|
prev_run: @prev_run,
|
|
prev_duration: @prev_duration,
|
|
prev_result: @prev_result,
|
|
current_owner: @current_owner
|
|
}.to_json
|
|
redis.zadd Manager.queue_key, @next_run , @klass
|
|
end
|
|
|
|
def del!
|
|
clear!
|
|
@next_run = @prev_run = @prev_result = @prev_duration = @current_owner = nil
|
|
end
|
|
|
|
def key
|
|
Manager.schedule_key(@klass)
|
|
end
|
|
|
|
def redis
|
|
@manager.redis
|
|
end
|
|
|
|
private
|
|
def clear!
|
|
key = Manager.schedule_key(@klass)
|
|
redis.del key
|
|
redis.zrem Manager.queue_key, key
|
|
end
|
|
|
|
end
|
|
end
|