Symphony::Metronome::
ScheduledEvent
class
A class the represents the relationship between an interval and an event.
- ds R
The sequel dataset representing this event.
- event R
The parsed interval expression.
- id R
The unique ID number of the scheduled event.
- options R
The options hash attached to this event.
- runtime R
The exact time that this event will run.
Return a set of all known events, sorted by date of execution. Delete any rows that are invalid expressions.
def self::load
events = SortedSet.new
self.db.disconnect
self.log.debug "Parsing/loading all actions."
self.db[ :metronome ].each do |event|
begin
event = new( event )
events << event
rescue ArgumentError, Symphony::Metronome::TimeParseError => err
self.log.error "%p while parsing \"%s\": %s" % [
err.class,
event[:expression],
err.message
]
self.log.debug " " + err.backtrace.join( "\n " )
self.db[ :metronome ].filter( :id => event[:id] ).delete
end
end
return events
end
Create a new ScheduledEvent
object.
def initialize( row )
@event = Symphony::Metronome::IntervalExpression.parse( row[:expression], row[:created] )
@options = row.delete( :options )
@id = row.delete( :id )
@ds = self.class.db[ :metronome ].filter( :id => self.id )
self.reset_runtime
unless self.class.splay.zero?
splay = Range.new( - self.class.splay, self.class.splay )
@runtime = self.runtime + rand( splay )
end
end
Comparable interface, order by next run time, soonest first.
def <=>( other )
return self.runtime <=> other.runtime
end
Permanently remove this event from the database.
def delete
self.log.debug "Removing action %p" % [ self.id ]
self.ds.delete
end
fire() { |opts, id| ... }
Perform the action attached to the event. Yields the deserialized options, the action ID to the supplied block if this event is okay to execute.
If the event is recurring, perform additional checks against the last run time.
Automatically remove the event if it has expired.
def fire
rv = self.event.fire?
if rv
opts = Yajl.load( self.options )
if self.event.recurring
now = Time.now
row = self.ds.first
if row
last = row[ :lastrun ]
return false if last && now - last < self.event.interval
end
self.ds.update( :lastrun => Time.now )
end
yield opts, self.id
end
self.delete if rv.nil?
return rv
end
Set the datetime that this event should fire next.
def reset_runtime
now = Time.now
if self.event.starting >= now
@runtime = self.event.starting
return
end
row = self.ds.first
if self.event.recurring && row
last = row[ :lastrun ]
if last && now > last
@runtime = now + self.event.interval - ( now - last )
else
@runtime = now + self.event.interval
end
else
@runtime = now + self.event.interval
end
end