# = Application # # The default Application object of the Framework. # # code: # George Moschovitis # Anastasios Koutoumanos # Elias Athanasopoulos # Elias Karakoulakis # # (c) 2004 Navel, all rights reserved. # $Id: application.rb 98 2004-10-22 07:36:20Z gmosx $ require 'optparse' require 'ostruct' require "n/logger" require "n/std" module N # == Application # # The default Application object of the Framework. # class Application # credentials of the application attr_accessor :name, :title, :description, :version # the status of the application # use symbols to denote status. # valid status symbols: # * :run = The server is running # * :stop = The server is stopped attr_accessor :status # startup time of the application attr_accessor :create_time # is the application daemonized? attr_reader :daemonized # the pid of the application attr_reader :pid, :pidfile # Intialize method # def initialize(name = "Unknown") @name = name @pidfile = "/tmp/#{@name}.pid" @create_time = Time.now() @status = :stop end # Parse the arguments passed to the application. # Some standard arguments are handled by default. # def parse_arguments(args = ARGV) opts = OptionParser.new { |opts| opts.banner = "Usage: application.rb [action]" opts.separator "" opts.separator "Specific options:" opts.on("-s", "--start", "Start Navel's Application Server.") { start() } opts.on("-S", "--stop", "Stop Navel's Application Server.") { stop() } opts.on("-r", "--restart", "Restart Navel's Application Server.") { restart() } opts.on("-d", "--daemon", "Run Navel's Application Server as a daemon.") { daemonize() start() } opts.on_tail("-?", "--help", "Show this message.") { puts opts exit } } begin opts.parse!(args) rescue => ex puts ex puts "Please, either specify a valid option or invoke the usage using -? or --help." end end alias_method :exec, :parse_arguments # # def start() raise "Application allready started!" unless :stop == @status begin run() rescue => ex puts ex end # to allow for chaining return self end # Override to properly restart the application # def restart() stop() start() # to allow for chaining return self end # Stop the application. Typically kills ths application daemon. # def stop if dpid = daemon_pid() begin File.delete(@pidfile) Process.kill("SIGKILL", dpid) $log.info "Successfully killed #{@name} instance, pid=#{dpid}" rescue => ex $log.error "Cannot kill #{@name} instance, pid=#{dpid}" $log.error ex end else $log.error "Cannot locate pid of running instance!" end # to allow for chaining return self end # Begin the application loop. # Override this method in your application. # def run # to allow for chaining return self end # Run the application as a daemon # FIXME: handle logging for daemons. # ???: How does this work !?!? # def daemonize unless @daemonized trap "SIGCLD", "IGNORE" pid = fork() if pid # parent process @pid = pid File.open(@pidfile, 'w') {|f| f << "#{pid}\n" } exit! else # child $log.info "Daemon for '#{@name}', process id: #{Process.pid}" end # change process group and lose control tty Process.setpgrp() end @daemonized = true return self end # Returns the pid of the running daemon # def daemon_pid() begin return File.open(@pidfile).read.chomp.to_i rescue $log.info "Could not read pid from #{@pidfile}" return nil end end end end # module