From 658f730c922e0ad3a5bb60ecf292831b6e6f4b75 Mon Sep 17 00:00:00 2001 From: luislavena Date: Mon, 27 Feb 2006 02:22:18 +0000 Subject: Added a option to select processor affinity for your mongrel service (-c INT or --cpu INT). Added indication of default environment used for service (production). Renamed configure method from MongrelRails to delayed_initialize (I think is more self descriptive now). git-svn-id: svn+ssh://rubyforge.org/var/svn/mongrel/trunk@63 19e92222-5c0b-0410-8929-a290d50e31e9 --- bin/mongrel_rails_service | 9 ++++++- bin/mongrel_rails_svc | 68 ++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 66 insertions(+), 11 deletions(-) (limited to 'bin') diff --git a/bin/mongrel_rails_service b/bin/mongrel_rails_service index 5478de1..50131ae 100644 --- a/bin/mongrel_rails_service +++ b/bin/mongrel_rails_service @@ -41,12 +41,13 @@ class InstallCommand < Mongrel::Command::Command ['-n', '--name SVC_NAME', "Required name for the service to be registered/installed.", :@svc_name, nil], ['-d', '--display SVC_DISPLAY', "Adjust the display name of the service.", :@svc_display, nil], ['-r', '--root PATH', "Set the root path where your rails app resides.", :@rails_root, Dir.pwd], - ['-e', '--environment ENV', "Rails environment to run as", :@environment, 'production'], + ['-e', '--environment ENV', "Rails environment to run as. (default: production)", :@environment, 'production'], ['-b', '--binding ADDR', "Address to bind to", :@ip, nil], ['-p', '--port PORT', "Which port to bind to", :@port, 3000], ['-m', '--mime PATH', "A YAML file that lists additional MIME types", :@mime_map, nil], ['-P', '--num-procs INT', "Number of processor threads to use", :@num_procs, nil], ['-t', '--timeout SECONDS', "Timeout all requests after SECONDS time", :@timeout, nil], + ['-c', '--cpu CPU', "Bind the process to specific cpu, starting from 1.", :@cpu, nil] ] end @@ -70,6 +71,9 @@ class InstallCommand < Mongrel::Command::Command valid? app_exist == true, "The root of rails app isn't valid, please verify." valid_exists? @mime_map, "MIME mapping file does not exist: #@mime_map" if @mime_map + # Validate the number of cpu to bind to. + valid? @cpu.to_i > 0, "You must specify a numeric value for cpu. (1..8)" if @cpu + # We should validate service existance here, right Zed? begin valid? !Service.exists?(@svc_name), "The service already exist, please uninstall it first." @@ -112,6 +116,9 @@ class InstallCommand < Mongrel::Command::Command # timeout @params << "-t #{@timeout.to_i} " if @timeout + + # cpu + @params << "-c #{@cpu.to_i} " if @cpu end def install_service diff --git a/bin/mongrel_rails_svc b/bin/mongrel_rails_svc index 53ec17b..bc65d66 100644 --- a/bin/mongrel_rails_svc +++ b/bin/mongrel_rails_svc @@ -10,6 +10,36 @@ require 'optparse' require 'win32/service' +# We need to use OpenProcess and SetProcessAffinityMask on WinNT/2K/XP for +# binding the process to each cpu. +# Kernel32 Module Just for Win32 :D +require 'dl/win32' + +module Kernel32 + [ + %w/OpenProcess LLL L/, + %w/SetProcessAffinityMask LL L/, + ].each do |fn| + const_set fn[0].intern, Win32API.new('kernel32.dll', *fn) + end + + PROCESS_ALL_ACCESS = 0x1f0fff + + module_function + + def set_affinity(pid, cpu) + handle = OpenProcess.call(PROCESS_ALL_ACCESS, 0, pid) + + # CPU mask is a bit weird, hehehe :) + # default mask for CPU 1 + mask = 1 + mask = %w{1 2 4 8 16 32 64 128}[cpu.to_i - 1] if cpu.to_i.between?(1, 8) + + SetProcessAffinityMask.call(handle, mask.to_i) + end +end +# End Kernel32 Module + DEBUG_LOG_FILE = File.expand_path(File.dirname(__FILE__) + '/debug.log') DEBUG_THREAD_LOG_FILE = File.expand_path(File.dirname(__FILE__) + '/debug_thread.log') @@ -67,8 +97,8 @@ class MongrelRails File.open(DEBUG_LOG_FILE,"a+") { |f| f.puts("#{Time.now} - mongrelrails_initialize left") } end - def configure - File.open(DEBUG_LOG_FILE,"a+") { |f| f.puts("#{Time.now} - mongrelrails_configure entered") } + def delayed_initialize + File.open(DEBUG_LOG_FILE,"a+") { |f| f.puts("#{Time.now} - delayed_initialize entered") } @rails = configure_rails #@rails = SimpleHandler.new @@ -77,7 +107,7 @@ class MongrelRails @server = Mongrel::HttpServer.new(@ip, @port, @num_procs.to_i, @timeout.to_i) @server.register("/", @rails) - File.open(DEBUG_LOG_FILE,"a+") { |f| f.puts("#{Time.now} - mongrelrails_configure left") } + File.open(DEBUG_LOG_FILE,"a+") { |f| f.puts("#{Time.now} - delayed_initialize left") } end def load_mime_map @@ -162,7 +192,7 @@ class RailsDaemon < Win32::Daemon def service_init File.open(DEBUG_LOG_FILE,"a+") { |f| f.puts("#{Time.now} - service_init entered") } - @rails.configure + @rails.delayed_initialize File.open(DEBUG_LOG_FILE,"a+") { |f| f.puts("#{Time.now} - service_init left") } end @@ -204,23 +234,33 @@ if ARGV[0] == 'service' :port => 3000, :mime_map => nil, :num_procs => 20, - :timeout => 120 + :timeout => 120, + :cpu => nil } ARGV.options do |opts| opts.on('-r', '--root PATH', "Set the root path where your rails app resides.") { |OPTIONS[:rails_root]| } - opts.on('-e', '--environment ENV', "Rails environment to run as.") { |OPTIONS[:environment]| } + opts.on('-e', '--environment ENV', "Rails environment to run as. (default: production)") { |OPTIONS[:environment]| } opts.on('-b', '--binding ADDR', "Address to bind to") { |OPTIONS[:ip]| } opts.on('-p', '--port PORT', "Which port to bind to") { |OPTIONS[:port]| } opts.on('-m', '--mime PATH', "A YAML file that lists additional MIME types") { |OPTIONS[:mime_map]| } opts.on('-P', '--num-procs INT', "Number of processor threads to use") { |OPTIONS[:num_procs]| } opts.on('-t', '--timeout SECONDS', "Timeout all requests after SECONDS time") { |OPTIONS[:timeout]| } - + opts.on('-c', '--cpu CPU', "Bind the process to specific cpu") { |OPTIONS[:cpu]| } + opts.parse! end + #expand RAILS_ROOT + OPTIONS[:rails_root] = File.expand_path(OPTIONS[:rails_root]) + OPTIONS[:docroot] = File.expand_path(OPTIONS[:rails_root] + '/public') + # We must bind to a specific cpu? + if OPTIONS[:cpu] + Kernel32.set_affinity(Process.pid, OPTIONS[:cpu]) + end + rails = MongrelRails.new(OPTIONS[:ip], OPTIONS[:port], OPTIONS[:rails_root], OPTIONS[:docroot], OPTIONS[:environment], OPTIONS[:mime_map], OPTIONS[:num_procs].to_i, OPTIONS[:timeout].to_i) rails_svc = RailsDaemon.new(rails) rails_svc.mainloop @@ -236,7 +276,8 @@ elsif ARGV[0] == 'debug' :port => 3000, :mime_map => nil, :num_procs => 20, - :timeout => 120 + :timeout => 120, + :cpu => nil } ARGV.options do |opts| @@ -247,7 +288,8 @@ elsif ARGV[0] == 'debug' opts.on('-m', '--mime PATH', "A YAML file that lists additional MIME types") { |OPTIONS[:mime_map]| } opts.on('-P', '--num-procs INT', "Number of processor threads to use") { |OPTIONS[:num_procs]| } opts.on('-t', '--timeout SECONDS', "Timeout all requests after SECONDS time") { |OPTIONS[:timeout]| } - + opts.on('-c', '--cpu CPU', "Bind the process to specific cpu") { |OPTIONS[:cpu]| } + opts.parse! end @@ -256,9 +298,15 @@ elsif ARGV[0] == 'debug' OPTIONS[:docroot] = File.expand_path(OPTIONS[:rails_root] + '/public') + # We must bind to a specific cpu? + if OPTIONS[:cpu] + Kernel32.set_affinity(Process.pid, OPTIONS[:cpu]) + end + rails = MongrelRails.new(OPTIONS[:ip], OPTIONS[:port], OPTIONS[:rails_root], OPTIONS[:docroot], OPTIONS[:environment], OPTIONS[:mime_map], OPTIONS[:num_procs].to_i, OPTIONS[:timeout].to_i) - rails.configure + rails.delayed_initialize rails.start_serve + begin sleep rescue Interrupt -- cgit v1.2.3-24-ge0c7