diff options
-rw-r--r-- | examples/mongrel_simple_ctrl.rb | 93 | ||||
-rw-r--r-- | examples/mongrel_simple_service.rb | 117 |
2 files changed, 208 insertions, 2 deletions
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 = "<html><body>Your request:<br /><pre>#{request.params.to_yaml}</pre><a href=\"/files\">View the files.</a></body></html>"
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 = "<html><body>Your request:<br /><pre>#{request.params.to_yaml}</pre><a href=\"/files\">View the files.</a></body></html>"
+ 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
|