diff options
Diffstat (limited to 'lib/mauve/server.rb')
-rw-r--r-- | lib/mauve/server.rb | 198 |
1 files changed, 80 insertions, 118 deletions
diff --git a/lib/mauve/server.rb b/lib/mauve/server.rb index 20f7045..307002f 100644 --- a/lib/mauve/server.rb +++ b/lib/mauve/server.rb @@ -16,34 +16,23 @@ require 'log4r' module Mauve - class Server - - DEFAULT_CONFIGURATION = { } - + class Server < MauveThread # # This is the order in which the threads should be started. # THREAD_CLASSES = [UDPServer, HTTPServer, Processor, Timer, Notifier, Heartbeat] - attr_accessor :hostname, :database, :initial_sleep - attr_reader :stopped_at, :started_at, :packet_buffer, :notification_buffer + attr_reader :hostname, :database, :initial_sleep + attr_reader :packet_buffer, :notification_buffer, :started_at include Singleton def initialize - # Set the logger up - - # Sleep time between pooling the @buffer buffer. - @sleep = 1 - - @frozen = false - @stop = false + super @hostname = "localhost" @database = "sqlite3:///./mauvealert.db" - - @stopped_at = MauveTime.now @started_at = MauveTime.now @initial_sleep = 300 @@ -53,29 +42,28 @@ module Mauve # @packet_buffer = [] @notification_buffer = [] + end + + def hostname=(h) + raise ArgumentError, "hostname must be a string" unless h.is_a?(String) + @hostname = h + end + + def database=(d) + raise ArgumentError, "database must be a string" unless d.is_a?(String) + @database = d + end - @config = DEFAULT_CONFIGURATION + def initial_sleep=(s) + raise ArgumentError, "initial_sleep must be numeric" unless s.is_a?(Numeric) + @initial_sleep = s end def logger @logger ||= Log4r::Logger.new(self.class.to_s) end - def configure(config_spec = nil) - # - # Update the configuration - # - if config_spec.nil? - # Do nothing - elsif config_spec.kind_of?(String) and File.exists?(config_spec) - @config.update(YAML.load_file(config_spec)) - elsif config_spec.kind_of?(Hash) - @config.update(config_spec) - else - raise ArgumentError.new("Unknown configuration spec "+config_spec.inspect) - end - - # + def setup DataMapper.setup(:default, @database) # DataObjects::Sqlite3.logger = Log4r::Logger.new("Mauve::DataMapper") @@ -86,119 +74,93 @@ module Mauve AlertChanged.auto_upgrade! History.auto_upgrade! Mauve::AlertEarliestDate.create_view! - - # - # Work out when the server was last stopped - # - # topped_at = self.last_heartbeat - end - - def last_heartbeat - # - # Work out when the last update was - # - [ Alert.last(:order => :updated_at.asc), - AlertChanged.last(:order => :updated_at.asc) ]. - reject{|a| a.nil? or a.updated_at.nil? }. - collect{|a| a.updated_at.to_time}. - sort. - last end - def freeze - @frozen = true - end + def start + self.state = :starting - def thaw - @thaw = true + self.setup + + self.run_thread { self.main_loop } end - def stop - if @stop - logger.debug("Stop already called!") - return - end - - @stop = true + alias run start + def main_loop thread_list = Thread.list thread_list.delete(Thread.current) THREAD_CLASSES.each do |klass| - thread_list.delete(klass.instance) - klass.instance.stop unless klass.instance.nil? - end - - thread_list.each do |t| - t.exit - end + # + # No need to double check ourselves. + # + thread_list.delete(klass.instance.thread) - logger.info("All threads stopped") - end + # + # Do nothing if we're frozen or supposed to be stopping or still alive! + # + next if self.should_stop? or klass.instance.alive? - def run - @stop = false - - loop do - thread_list = Thread.list - - thread_list.delete(Thread.current) - - THREAD_CLASSES.each do |klass| - # - # No need to double check ourselves. - # - thread_list.delete(klass.instance.thread) - - # - # Do nothing if we're frozen or supposed to be stopping or still alive! - # - next if @frozen or @stop or klass.instance.alive? - - # - # ugh something is beginnging to smell. - # - begin - klass.instance.join - rescue StandardError => ex - logger.error "Caught #{ex.to_s} whilst checking #{klass} thread" - logger.debug ex.backtrace.join("\n") - end - - # - # (re-)start the klass. - # - klass.instance.start unless @stop + # + # ugh something is beginnging to smell. + # + begin + klass.instance.join + rescue StandardError => ex + logger.error "Caught #{ex.to_s} whilst checking #{klass} thread" + logger.debug ex.backtrace.join("\n") end # - # Now do the same with other threads. However if these ones crash, the - # server has to stop, as there is no method to restart them. + # (re-)start the klass. # - thread_list.each do |t| + klass.instance.start unless self.should_stop? + end - next if t.alive? + # + # Now do the same with other threads. However if these ones crash, the + # server has to stop, as there is no method to restart them. + # + thread_list.each do |t| - begin - t.join - rescue StandardError => ex - logger.fatal "Caught #{ex.to_s} whilst checking threads" - logger.debug ex.backtrace.join("\n") - self.stop - break - end + next if self.should_stop? or t.alive? + begin + t.join + rescue StandardError => ex + logger.fatal "Caught #{ex.to_s} whilst checking threads" + logger.debug ex.backtrace.join("\n") + self.stop + break end - break if @stop + end + end + + def stop + if self.state == :stopping + # uh-oh already told to stop. + logger.error "Stop already called. Killing self!" + Kernel.exit 1 + end + + self.state = :stopping - sleep 1 + THREAD_CLASSES.each do |klass| + klass.instance.stop unless klass.instance.nil? end - logger.debug("Thread stopped") + + thread_list = Thread.list + thread_list.delete(Thread.current) + + thread_list.each do |t| + t.exit + end + + self.state = :stopped end - alias start run class << self |