class Symphony::Metronome::Scheduler

Manage the delta queue of events and associated actions.

Constants

CONFIG_DEFAULTS
SIGNALS

Signals the daemon responds to.

Attributes

listen[R]

Should Metronome register and schedule events via AMQP? If false, you'll need a separate way to add event actions to the database, and manually HUP the daemon.

queue[R]

The sorted set of ScheduledEvent objects.

Public Class Methods

configure( config=nil ) click to toggle source

Configurability API

# File lib/symphony/metronome/scheduler.rb, line 33
def self::configure( config=nil )
        config = self.defaults.merge( config || {} )
        @listen = config.delete( :listen )
end
run( &block ) click to toggle source

Create and start an instanced daemon.

# File lib/symphony/metronome/scheduler.rb, line 41
def self::run( &block )
        return new( block )
end

Protected Instance Methods

handle_signal( sig ) click to toggle source

Dispatch incoming signals to appropriate handlers.

# File lib/symphony/metronome/scheduler.rb, line 113
def handle_signal( sig )
        case sig
        when :TERM, :INT
                @running = false
                Process.kill( sig.to_s, @child ) if self.class.listen

        when :HUP
                @queue = Symphony::Metronome::ScheduledEvent.load
                self.queue.each{|ev| ev.fire(&@proc) if ev.event.recurring }

        else
                self.log.debug "Unhandled signal: %s" % [ sig ]
        end
end
process_events() click to toggle source

Process all events that have reached their runtime.

# File lib/symphony/metronome/scheduler.rb, line 131
def process_events
        now = Time.now

        self.queue.each do |ev|
                next unless now >= ev.runtime

                self.queue.delete( ev )
                rv = ev.fire( &@proc )

                # Reschedule the event and place it back on the queue.
                #
                if ev.event.recurring
                        ev.reset_runtime
                        self.queue.add( ev ) unless rv.nil?

                # It was a single run event, torch it!
                #
                else
                        ev.delete

                end
        end
end
start() click to toggle source

Main daemon sleep loop.

# File lib/symphony/metronome/scheduler.rb, line 90
def start
        $0 = "Metronome%s" % [ self.class.listen ? ' (executor)' : '' ]
        @running = true

        loop do
                wait = nil

                if ev = self.queue.first
                        wait = ev.runtime - Time.now
                        wait = 0 if wait < 0
                        self.log.info "Next event in %0.3f second(s) (id: %d)..." % [ wait, ev.id ]
                else
                        self.log.warn "No events scheduled.  Waiting indefinitely..."
                end

                self.process_events unless self.wait_for_signals( wait )
                break unless @running
        end
end