2014-01-30 16:21:38 +11:00
module Scheduler
class ScheduleInfo
attr_accessor :next_run ,
:prev_run ,
:prev_duration ,
2014-02-12 13:32:34 +11:00
:prev_result ,
:current_owner
2014-01-30 16:21:38 +11:00
def initialize ( klass , manager )
@klass = klass
@manager = manager
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 " ]
2014-02-12 13:32:34 +11:00
@current_owner = data [ " current_owner " ]
2014-01-30 16:21:38 +11:00
end
rescue
# corrupt redis
2014-02-12 13:32:34 +11:00
@next_run = @prev_run = @prev_result = @prev_duration = @current_owner = nil
2014-01-30 16:21:38 +11:00
end
def valid?
return false unless @next_run
2014-03-14 13:02:21 -04:00
( ! @prev_run && @next_run < Time . now . to_i + 5 . minutes ) || valid_every? || valid_daily?
end
def valid_every?
return false unless @klass . every
2014-09-25 17:44:48 +02:00
! ! @prev_run &&
2014-01-30 16:21:38 +11:00
@prev_run < = Time . now . to_i &&
@next_run < @prev_run + @klass . every * ( 1 + @manager . random_ratio )
end
2014-03-14 13:02:21 -04:00
def valid_daily?
return false unless @klass . daily
2014-09-25 17:44:48 +02:00
! ! @prev_run &&
@prev_run < = Time . now . to_i &&
@next_run < @prev_run + 1 . day
2014-03-14 13:02:21 -04:00
end
def schedule_every!
2014-01-30 16:21:38 +11:00
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
2014-03-14 13:02:21 -04:00
end
def schedule_daily!
return if valid?
at = @klass . daily [ :at ] || 0
today_begin = Time . now . midnight . to_i
today_offset = DateTime . now . seconds_since_midnight
# If it's later today
if at > today_offset
@next_run = today_begin + at
else
# Otherwise do it tomorrow
@next_run = today_begin + 1 . day + at
end
end
def schedule!
if @klass . every
schedule_every!
elsif @klass . daily
schedule_daily!
end
2014-01-30 16:21:38 +11:00
write!
end
def write!
2015-06-26 13:32:08 +10:00
2014-01-30 16:21:38 +11:00
clear!
redis . set key , {
next_run : @next_run ,
prev_run : @prev_run ,
prev_duration : @prev_duration ,
2014-02-12 13:32:34 +11:00
prev_result : @prev_result ,
current_owner : @current_owner
2014-01-30 16:21:38 +11:00
} . to_json
2014-04-17 15:57:17 +10:00
2015-06-26 13:32:08 +10:00
redis . zadd queue_key , @next_run , @klass
2014-01-30 16:21:38 +11:00
end
def del!
clear!
2014-02-12 13:32:34 +11:00
@next_run = @prev_run = @prev_result = @prev_duration = @current_owner = nil
2014-01-30 16:21:38 +11:00
end
def key
2015-06-26 13:32:08 +10:00
if @klass . is_per_host
Manager . schedule_key ( @klass , @manager . hostname )
else
Manager . schedule_key ( @klass )
end
end
def queue_key
if @klass . is_per_host
Manager . queue_key ( @manager . hostname )
else
Manager . queue_key
end
2014-01-30 16:21:38 +11:00
end
def redis
@manager . redis
end
private
def clear!
redis . del key
2015-06-26 13:32:08 +10:00
redis . zrem queue_key , @klass
2014-01-30 16:21:38 +11:00
end
end
end