# This script emualtes script/server behavior but running webrick http server require 'rubygems' require 'mongrel' require 'yaml' require 'zlib' require 'win32/service' DEBUG_LOG_FILE = File.expand_path(File.dirname(__FILE__) + '/debug.log') class SimpleHandler < Mongrel::HttpHandler def process(request, response) response.start do |head,out| head["Content-Type"] = "text/html" results = "Your request:
#{request.params.to_yaml}
View the files." if request.params["HTTP_ACCEPT_ENCODING"] == "gzip,deflate" head["Content-Encoding"] = "deflate" # send it back deflated out << Zlib::Deflate.deflate(results) else # no gzip supported, send it back normal out << results end end end end class MongrelDaemon < Win32::Daemon def initialize(options) @options = options end def service_init File.open(DEBUG_LOG_FILE,"a+") { |f| f.puts("#{Time.now} - service_init entered") } File.open(DEBUG_LOG_FILE,"a+") { |f| f.puts("Mongrel running on #{@options[:ip]}:#{@options[:port]} with docroot #{@options[:server_root]}") } @simple = SimpleHandler.new @files = Mongrel::DirHandler.new(@options[:server_root]) @http_server = Mongrel::HttpServer.new(@options[:ip], @options[:port]) @http_server.register("/", @simple) @http_server.register("/files", @files) File.open(DEBUG_LOG_FILE,"a+") { |f| f.puts("#{Time.now} - service_init left") } end def service_stop File.open(DEBUG_LOG_FILE,"a+"){ |f| f.puts "stop signal received: " + Time.now.to_s f.puts "sending stop to mongrel threads: " + Time.now.to_s } #@http_server.stop end def service_pause File.open(DEBUG_LOG_FILE,"a+"){ |f| f.puts "pause signal received: " + Time.now.to_s } end def service_resume File.open(DEBUG_LOG_FILE,"a+"){ |f| f.puts "continue/resume signal received: " + Time.now.to_s } end def service_main File.open(DEBUG_LOG_FILE,"a+") { |f| f.puts("#{Time.now} - service_main entered") } begin File.open(DEBUG_LOG_FILE,"a+") { |f| f.puts("#{Time.now} - http_server.run") } @http_server.run # No runner thread was needed after all! #@runner = Thread.new do # @http_server.acceptor.join #end #File.open("d:\\test.log","a+") { |f| f.puts("#{Time.now} - runner.run") } #@runner.run # here is where magic happens! # if put blocking code here, the thread never left service_main, and the rb_func_call in service.c # never exit, even if the stop signal is received. # # to probe my theory, just comment the while loop and remove the '1' from sleep function # service start ok, but fail to stop. # # Even if no functional code is in service_main (because we have other working threads), # we must monitor the state of the service to exit when the STOP event is received. # # Note: maybe not loop in 1 second intervals? while state == RUNNING sleep 1 end rescue StandardError, Exception, interrupt => err File.open(DEBUG_LOG_FILE,"a+"){ |f| f.puts("#{Time.now} - Error: #{err}") } File.open(DEBUG_LOG_FILE,"a+"){ |f| f.puts("BACKTRACE: " + err.backtrace.join("\n")) } end File.open(DEBUG_LOG_FILE,"a+") { |f| f.puts("#{Time.now} - service_main left") } end end OPTIONS = { :port => 3000, :ip => "0.0.0.0", :server_root => File.expand_path(File.dirname(__FILE__)), } web_server = MongrelDaemon.new(OPTIONS) web_server.mainloop