Add 'last run' timestamps for recurring events, and take these into
account when firing events on daemon rescheduling (via HUP.) FossilOrigin-Name: 1620e80e8bddd27741569dea0ff4bd84ba29429861ed49d17f5777c238ae4876
This commit is contained in:
parent
b18647f6a5
commit
7c2954b0ad
6 changed files with 79 additions and 8 deletions
|
|
@ -9,7 +9,7 @@ module Symphony::Metronome
|
|||
Configurability
|
||||
|
||||
# Library version constant
|
||||
VERSION = '0.1.0'
|
||||
VERSION = '0.2.0'
|
||||
|
||||
# Version-control revision constant
|
||||
REVISION = %q$Revision$
|
||||
|
|
@ -74,6 +74,5 @@ module Symphony::Metronome
|
|||
return Symphony::Metronome::Scheduler.run( &block )
|
||||
end
|
||||
|
||||
|
||||
end # Symphony::Metronome
|
||||
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ class Symphony::Metronome::ScheduledEvent
|
|||
# Configure defaults.
|
||||
#
|
||||
CONFIG_DEFAULTS = {
|
||||
db: 'sqlite:///tmp/metronome.db',
|
||||
splay: 0
|
||||
:db => 'sqlite:///tmp/metronome.db',
|
||||
:splay => 0
|
||||
}
|
||||
|
||||
class << self
|
||||
|
|
@ -52,6 +52,7 @@ class Symphony::Metronome::ScheduledEvent
|
|||
#
|
||||
migrations_dir = Symphony::Metronome::DATADIR + 'migrations'
|
||||
unless Sequel::Migrator.is_current?( self.db, migrations_dir.to_s )
|
||||
Loggability[ Symphony ].info "Installing database schema..."
|
||||
Sequel::Migrator.apply( self.db, migrations_dir.to_s )
|
||||
end
|
||||
end
|
||||
|
|
@ -97,6 +98,8 @@ class Symphony::Metronome::ScheduledEvent
|
|||
@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?
|
||||
|
|
@ -105,6 +108,9 @@ class Symphony::Metronome::ScheduledEvent
|
|||
end
|
||||
end
|
||||
|
||||
# The sequel dataset representing this event.
|
||||
attr_reader :ds
|
||||
|
||||
# The parsed interval expression.
|
||||
attr_reader :event
|
||||
|
||||
|
|
@ -133,7 +139,21 @@ class Symphony::Metronome::ScheduledEvent
|
|||
# Otherwise, the event should already be running (start time has already
|
||||
# elapsed), so schedule it forward on it's next interval iteration.
|
||||
#
|
||||
@runtime = now + self.event.interval
|
||||
# If it's a recurring event that has run before, consider the elapsed time
|
||||
# as part of the next calculation.
|
||||
#
|
||||
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
|
||||
|
||||
|
||||
|
|
@ -141,13 +161,32 @@ class Symphony::Metronome::ScheduledEvent
|
|||
### 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?
|
||||
|
||||
# Just based on the expression parser, is this event ready to fire?
|
||||
#
|
||||
if rv
|
||||
opts = Yajl.load( self.options )
|
||||
|
||||
# Don't fire recurring events unless their interval has elapsed.
|
||||
# This prevents events from triggering when the daemon receives
|
||||
# a HUP.
|
||||
#
|
||||
if self.event.recurring
|
||||
now = Time.now
|
||||
last = self.ds.first[ :lastrun ]
|
||||
return false if last && now - last < self.event.interval
|
||||
|
||||
# Mark the time this recurring event was fired.
|
||||
self.ds.update( :lastrun => Time.now )
|
||||
end
|
||||
|
||||
yield opts, self.id
|
||||
end
|
||||
|
||||
|
|
@ -160,7 +199,7 @@ class Symphony::Metronome::ScheduledEvent
|
|||
###
|
||||
def delete
|
||||
self.log.debug "Removing action %p" % [ self.id ]
|
||||
self.class.db[ :metronome ].filter( :id => self.id ).delete
|
||||
self.ds.delete
|
||||
end
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ class Symphony::Metronome::Scheduler
|
|||
SIGNALS = [ :HUP, :INT, :TERM ]
|
||||
|
||||
CONFIG_DEFAULTS = {
|
||||
:listen => true
|
||||
:listen => false
|
||||
}
|
||||
|
||||
class << self
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue