#!/usr/bin/env ruby -w if $0 == __FILE__ then module Borges; end require 'Borges/RequestHandler/RequestHandler' require 'Borges/RequestHandler/Dispatcher' Borges::Dispatcher.url_prefix = (ARGV.shift || "/cgi-bin/borges") end require 'drb' require 'rinda/ring' require 'Borges' require 'Borges/DRb' class Borges::DRbServer include DRbUndumped ## # Turn a block into a daemon process # # TODO: Write pid to file def self.daemonize fork do Process.setsid fork and exit Dir.chdir "/" File.umask 0000 STDIN.reopen "/dev/null" STDOUT.reopen "/dev/null", "a" STDERR.reopen STDOUT yield end end def self.create DRb.start_service provide_tried = false begin ::Rinda::RingFinger.new.lookup_ring_any # test for RingServer rescue RuntimeError => e # HACK: ugly, ugly, make RingNotFound an Exception subclass if e.message == 'RingNotFound' and not provide_tried then STDERR.puts "Spawning RingServer" provide_tried = true self.daemonize do require 'rinda/tuplespace' $0 = 'Borges RingServer' DRb.start_service Rinda::RingServer.new Rinda::TupleSpace.new DRb.thread.join end sleep 1 retry else raise "Unable to start RingServer" end end borges_server = self.new service = ::Rinda::RingProvider.new :Borges, borges_server, "Borges Server" service.provide return borges_server end # TODO: on shutdown, unlist service in RingServer def self.start borges_server = create trap('INT') do #::Rinda::RingFinger.primary.take [:name, :Borges, borges_server, # "Borges Server"] DRb.stop_service end DRb.thread.join end def initialize @handler = Borges::Dispatcher.instance end def handle_request(request) begin return @handler.handle_request(request) rescue Exception => e puts "!!" puts e.backtrace.join("\n") puts "!!" raise e end end end # class Borges::DRbServer if $0 == __FILE__ then Borges::DRbServer.start end