From cae898c5a54d27240d57f87133edbf8cf2a02744 Mon Sep 17 00:00:00 2001 From: luislavena Date: Tue, 21 Feb 2006 05:48:37 +0000 Subject: Corrected simple service and controller due Macintosh carrier returns (CR) incompatible with win32 ruby (CRLF) (actally that made the scripts useless, now solved). git-svn-id: svn+ssh://rubyforge.org/var/svn/mongrel/trunk@54 19e92222-5c0b-0410-8929-a290d50e31e9 --- examples/mongrel_simple_ctrl.rb | 93 ++++++++++++++++++++++++++++- examples/mongrel_simple_service.rb | 117 ++++++++++++++++++++++++++++++++++++- 2 files changed, 208 insertions(+), 2 deletions(-) (limited to 'examples') diff --git a/examples/mongrel_simple_ctrl.rb b/examples/mongrel_simple_ctrl.rb index 7ab82eb..4663d1c 100644 --- a/examples/mongrel_simple_ctrl.rb +++ b/examples/mongrel_simple_ctrl.rb @@ -1 +1,92 @@ -############################################### # mongrel_simple_ctrl.rb # # Control script for the Mongrel server ############################################### require "optparse" require "win32/service" include Win32 # I start the service name with an 'A' so that it appears at the top SERVICE_NAME = "MongrelSvc" SERVICE_DISPLAYNAME = "Mongrel HTTP Server" SCRIPT_ROOT = File.join(File.dirname(__FILE__), '.') SCRIPT_NAME = "mongrel_simple_service.rb" SERVICE_SCRIPT = File.expand_path(SCRIPT_ROOT + '/' + SCRIPT_NAME) OPTIONS = {} ARGV.options do |opts| opts.on("-d", "--delete", "Delete the service"){ OPTIONS[:delete] = true } opts.on("-u", "--uninstall","Delete the service"){ OPTIONS[:uninstall] = true } opts.on("-s", "--start", "Start the service"){ OPTIONS[:start] = true } opts.on("-x", "--stop", "Stop the service"){ OPTIONS[:stop] = true } opts.on("-i", "--install","Install the service"){ OPTIONS[:install] = true } opts.on("-h", "--help", "Show this help message."){ puts opts; exit } opts.parse! end # Install the service if OPTIONS[:install] require 'rbconfig' svc = Service.new svc.create_service{ |s| s.service_name = SERVICE_NAME s.display_name = SERVICE_DISPLAYNAME s.binary_path_name = Config::CONFIG['bindir'] + '/ruby ' + SERVICE_SCRIPT s.dependencies = [] } svc.close puts "#{SERVICE_DISPLAYNAME} service installed" end # Start the service if OPTIONS[:start] Service.start(SERVICE_NAME) started = false while started == false s = Service.status(SERVICE_NAME) started = true if s.current_state == "running" break if started == true puts "One moment, " + s.current_state sleep 1 end puts "#{SERVICE_DISPLAYNAME} service started" end # Stop the service if OPTIONS[:stop] Service.stop(SERVICE_NAME) stopped = false while stopped == false s = Service.status(SERVICE_NAME) stopped = true if s.current_state == "stopped" break if stopped == true puts "One moment, " + s.current_state sleep 1 end puts "#{SERVICE_DISPLAYNAME} service stopped" end # Delete the service. Stop it first. if OPTIONS[:delete] || OPTIONS[:uninstall] begin Service.stop(SERVICE_NAME) rescue end begin Service.delete(SERVICE_NAME) rescue end puts "#{SERVICE_DISPLAYNAME} service deleted" end # END mongrel_rails_ctrl.rb \ No newline at end of file +############################################### +# mongrel_simple_ctrl.rb +# +# Control script for the Mongrel server +############################################### +require "optparse" +require "win32/service" +include Win32 + +# I start the service name with an 'A' so that it appears at the top +SERVICE_NAME = "MongrelSvc" +SERVICE_DISPLAYNAME = "Mongrel HTTP Server" +SCRIPT_ROOT = File.join(File.dirname(__FILE__), '.') +SCRIPT_NAME = "mongrel_simple_service.rb" +SERVICE_SCRIPT = File.expand_path(SCRIPT_ROOT + '/' + SCRIPT_NAME) + +OPTIONS = {} + +ARGV.options do |opts| + opts.on("-d", "--delete", "Delete the service"){ OPTIONS[:delete] = true } + opts.on("-u", "--uninstall","Delete the service"){ OPTIONS[:uninstall] = true } + opts.on("-s", "--start", "Start the service"){ OPTIONS[:start] = true } + opts.on("-x", "--stop", "Stop the service"){ OPTIONS[:stop] = true } + opts.on("-i", "--install","Install the service"){ OPTIONS[:install] = true } + + opts.on("-h", "--help", "Show this help message."){ puts opts; exit } + + opts.parse! +end + +# Install the service +if OPTIONS[:install] + require 'rbconfig' + + svc = Service.new + svc.create_service{ |s| + s.service_name = SERVICE_NAME + s.display_name = SERVICE_DISPLAYNAME + s.binary_path_name = Config::CONFIG['bindir'] + '/ruby ' + SERVICE_SCRIPT + s.dependencies = [] + } + svc.close + puts "#{SERVICE_DISPLAYNAME} service installed" +end + +# Start the service +if OPTIONS[:start] + Service.start(SERVICE_NAME) + started = false + while started == false + s = Service.status(SERVICE_NAME) + started = true if s.current_state == "running" + break if started == true + puts "One moment, " + s.current_state + sleep 1 + end + puts "#{SERVICE_DISPLAYNAME} service started" +end + +# Stop the service +if OPTIONS[:stop] + Service.stop(SERVICE_NAME) + stopped = false + while stopped == false + s = Service.status(SERVICE_NAME) + stopped = true if s.current_state == "stopped" + break if stopped == true + puts "One moment, " + s.current_state + sleep 1 + end + puts "#{SERVICE_DISPLAYNAME} service stopped" +end + +# Delete the service. Stop it first. +if OPTIONS[:delete] || OPTIONS[:uninstall] + begin + Service.stop(SERVICE_NAME) + rescue + end + begin + Service.delete(SERVICE_NAME) + rescue + end + puts "#{SERVICE_DISPLAYNAME} service deleted" +end +# END mongrel_rails_ctrl.rb + + + + + + diff --git a/examples/mongrel_simple_service.rb b/examples/mongrel_simple_service.rb index f8a2f06..8e82c7b 100644 --- a/examples/mongrel_simple_service.rb +++ b/examples/mongrel_simple_service.rb @@ -1 +1,116 @@ -# This script emualtes script/server behavior but running webrick http server require 'rubygems' require 'mongrel' require 'yaml' require 'zlib' require 'win32/service' 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 MongrelThread < Thread def initialize(mongrel_server) @server = mongrel_server end def run @server.acceptor.join end end class MongrelDaemon < Win32::Daemon attr_reader :http_server def initialize(options) @options = options end def service_init File.open("d:\\test.log","a+") { |f| f.puts("#{Time.now} - service_init entered") } File.open("d:\\test.log","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("d:\\test.log","a+") { |f| f.puts("#{Time.now} - service_init left") } end def service_stop File.open("d:\\test.log","a+"){ |f| f.puts "stop signal received: " + Time.now.to_s } end def service_pause File.open("d:\\test.log","a+"){ |f| f.puts "pause signal received: " + Time.now.to_s } end def service_resume File.open("d:\\test.log","a+"){ |f| f.puts "continue/resume signal received: " + Time.now.to_s } end def service_main File.open("d:\\test.log","a+") { |f| f.puts("#{Time.now} - service_main entered") } begin File.open("d:\\test.log","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("d:\\test.log","a+"){ |f| f.puts("#{Time.now} - Error: #{err}") } File.open("d:\\test.log","a+"){ |f| f.puts("BACKTRACE: " + err.backtrace.join("\n")) } end File.open("d:\\test.log","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 \ No newline at end of file +# 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 -- cgit v1.2.3-24-ge0c7