macournoyer / thin

A very fast & simple Ruby web server

This URL has Read+Write access

thin / lib / thin / runner.rb
401ade74 » macournoyer 2008-02-01 Refactoring thin script in ... 1 require 'optparse'
2 require 'yaml'
3
af63af25 » macournoyer 2008-03-13 * Guess which adapter to us... 4 module Thin
401ade74 » macournoyer 2008-02-01 Refactoring thin script in ... 5 # CLI runner.
6 # Parse options and send command to the correct Controller.
7 class Runner
117e405e » macournoyer 2008-02-02 * Add a script to run thin ... 8 COMMANDS = %w(start stop restart config)
348f6e4d » macournoyer 2008-02-03 Change thin service install... 9 LINUX_ONLY_COMMANDS = %w(install)
117e405e » macournoyer 2008-02-02 * Add a script to run thin ... 10
348f6e4d » macournoyer 2008-02-03 Change thin service install... 11 # Commands that wont load options from the config file
117e405e » macournoyer 2008-02-02 * Add a script to run thin ... 12 CONFIGLESS_COMMANDS = %w(config install)
401ade74 » macournoyer 2008-02-01 Refactoring thin script in ... 13
be65e98b » macournoyer 2008-02-01 Add specs for Runner and Co... 14 # Parsed options
15 attr_accessor :options
16
348f6e4d » macournoyer 2008-02-03 Change thin service install... 17 # Name of the command to be runned.
be65e98b » macournoyer 2008-02-01 Add specs for Runner and Co... 18 attr_accessor :command
19
348f6e4d » macournoyer 2008-02-03 Change thin service install... 20 # Arguments to be passed to the command.
21 attr_accessor :arguments
22
23 # Return all available commands
24 def self.commands
25 commands = COMMANDS
26 commands += LINUX_ONLY_COMMANDS if Thin.linux?
27 commands
28 end
29
401ade74 » macournoyer 2008-02-01 Refactoring thin script in ... 30 def initialize(argv)
31 @argv = argv
32
33 # Default options values
34 @options = {
2b7d72da » macournoyer 2008-02-20 * Add --max-persistent-conn... 35 :chdir => Dir.pwd,
36 :environment => 'development',
37 :address => '0.0.0.0',
38 :port => Server::DEFAULT_PORT,
39 :timeout => Server::DEFAULT_TIMEOUT,
40 :log => 'log/thin.log',
41 :pid => 'tmp/pids/thin.pid',
42 :max_conns => Server::DEFAULT_MAXIMUM_CONNECTIONS,
43 :max_persistent_conns => Server::DEFAULT_MAXIMUM_PERSISTENT_CONNECTIONS
401ade74 » macournoyer 2008-02-01 Refactoring thin script in ... 44 }
0bba5f17 » macournoyer 2008-02-02 Add specs for Runner. 45
46 parse!
401ade74 » macournoyer 2008-02-01 Refactoring thin script in ... 47 end
48
49 def parser
50 # NOTE: If you add an option here make sure the key in the +options+ hash is the
51 # same as the name of the command line option.
52 # +option+ keys are used to build the command line to launch other processes,
53 # see <tt>lib/thin/command.rb</tt>.
be65e98b » macournoyer 2008-02-01 Add specs for Runner and Co... 54 @parser ||= OptionParser.new do |opts|
348f6e4d » macournoyer 2008-02-03 Change thin service install... 55 opts.banner = "Usage: thin [options] #{self.class.commands.join('|')}"
401ade74 » macournoyer 2008-02-01 Refactoring thin script in ... 56
57 opts.separator ""
58 opts.separator "Server options:"
59
60 opts.on("-a", "--address HOST", "bind to HOST address " +
117e405e » macournoyer 2008-02-02 * Add a script to run thin ... 61 "(default: #{@options[:address]})") { |host| @options[:address] = host }
62 opts.on("-p", "--port PORT", "use PORT (default: #{@options[:port]})") { |port| @options[:port] = port.to_i }
63 opts.on("-S", "--socket FILE", "bind to unix domain socket") { |file| @options[:socket] = file }
1f3072c9 » macournoyer 2008-02-08 Add Swiftiply support to Cl... 64 opts.on("-y", "--swiftiply [KEY]", "Run using swiftiply") { |key| @options[:swiftiply] = key }
dc472b68 » macournoyer 2008-04-05 Refactor Rack loader. 65 opts.on("-A", "--adapter NAME", "Rack adapter to use (default: autodetect)",
c0324bfe » mtodd 2008-07-01 Simplify printing the adapt... 66 "(#{Rack::ADAPTERS.map{|(a,b)|a}.join(', ')})") { |name| @options[:adapter] = name }
a3a783e2 » macournoyer 2008-04-05 Add --require (-r) option t... 67 opts.on("-R", "--rackup FILE", "Load a Rack config file instead of " +
dc472b68 » macournoyer 2008-04-05 Refactor Rack loader. 68 "Rack adapter") { |file| @options[:rackup] = file }
69 opts.on("-c", "--chdir DIR", "Change to dir before starting") { |dir| @options[:chdir] = File.expand_path(dir) }
117e405e » macournoyer 2008-02-02 * Add a script to run thin ... 70 opts.on( "--stats PATH", "Mount the Stats adapter under PATH") { |path| @options[:stats] = path }
71
af63af25 » macournoyer 2008-03-13 * Guess which adapter to us... 72 opts.separator ""
dc472b68 » macournoyer 2008-04-05 Refactor Rack loader. 73 opts.separator "Adapter options:"
74 opts.on("-e", "--environment ENV", "Framework environment " +
af63af25 » macournoyer 2008-03-13 * Guess which adapter to us... 75 "(default: #{@options[:environment]})") { |env| @options[:environment] = env }
76 opts.on( "--prefix PATH", "Mount the app under PATH (start with /)") { |path| @options[:prefix] = path }
77
117e405e » macournoyer 2008-02-02 * Add a script to run thin ... 78 unless Thin.win? # Daemonizing not supported on Windows
79 opts.separator ""
80 opts.separator "Daemon options:"
401ade74 » macournoyer 2008-02-01 Refactoring thin script in ... 81
117e405e » macournoyer 2008-02-02 * Add a script to run thin ... 82 opts.on("-d", "--daemonize", "Run daemonized in the background") { @options[:daemonize] = true }
83 opts.on("-l", "--log FILE", "File to redirect output " +
84 "(default: #{@options[:log]})") { |file| @options[:log] = file }
85 opts.on("-P", "--pid FILE", "File to store PID " +
86 "(default: #{@options[:pid]})") { |file| @options[:pid] = file }
87 opts.on("-u", "--user NAME", "User to run daemon as (use with -g)") { |user| @options[:user] = user }
88 opts.on("-g", "--group NAME", "Group to run daemon as (use with -u)") { |group| @options[:group] = group }
401ade74 » macournoyer 2008-02-01 Refactoring thin script in ... 89
117e405e » macournoyer 2008-02-02 * Add a script to run thin ... 90 opts.separator ""
91 opts.separator "Cluster options:"
401ade74 » macournoyer 2008-02-01 Refactoring thin script in ... 92
dcb1c19e » macournoyer 2008-02-06 --servers 1 is now consider... 93 opts.on("-s", "--servers NUM", "Number of servers to start") { |num| @options[:servers] = num.to_i }
117e405e » macournoyer 2008-02-02 * Add a script to run thin ... 94 opts.on("-o", "--only NUM", "Send command to only one server of the cluster") { |only| @options[:only] = only }
95 opts.on("-C", "--config FILE", "Load options from config file") { |file| @options[:config] = file }
348f6e4d » macournoyer 2008-02-03 Change thin service install... 96 opts.on( "--all [DIR]", "Send command to each config files in DIR") { |dir| @options[:all] = dir } if Thin.linux?
117e405e » macournoyer 2008-02-02 * Add a script to run thin ... 97 end
98
401ade74 » macournoyer 2008-02-01 Refactoring thin script in ... 99 opts.separator ""
2b7d72da » macournoyer 2008-02-20 * Add --max-persistent-conn... 100 opts.separator "Tuning options:"
101
dc472b68 » macournoyer 2008-04-05 Refactor Rack loader. 102 opts.on("-b", "--backend CLASS", "Backend to use, full classname") { |name| @options[:backend] = name }
2b7d72da » macournoyer 2008-02-20 * Add --max-persistent-conn... 103 opts.on("-t", "--timeout SEC", "Request or command timeout in sec " +
104 "(default: #{@options[:timeout]})") { |sec| @options[:timeout] = sec.to_i }
b21e9003 » macournoyer 2008-02-21 Align code to make more pretty 105 opts.on( "--max-conns NUM", "Maximum number of connections " +
106 "(default: #{@options[:max_conns]})",
107 "Might require sudo to set higher then 1024") { |num| @options[:max_conns] = num.to_i } unless Thin.win?
2b7d72da » macournoyer 2008-02-20 * Add --max-persistent-conn... 108 opts.on( "--max-persistent-conns NUM",
b21e9003 » macournoyer 2008-02-21 Align code to make more pretty 109 "Maximum number of persistent connections",
110 "(default: #{@options[:max_persistent_conns]})") { |num| @options[:max_persistent_conns] = num.to_i }
5fb7b232 » macournoyer 2008-04-05 Add a note to threaded mode... 111 opts.on( "--threaded", "Call the Rack application in threads " +
112 "[experimental]") { @options[:threaded] = true }
2b7d72da » macournoyer 2008-02-20 * Add --max-persistent-conn... 113
114 opts.separator ""
401ade74 » macournoyer 2008-02-01 Refactoring thin script in ... 115 opts.separator "Common options:"
116
a3a783e2 » macournoyer 2008-04-05 Add --require (-r) option t... 117 opts.on_tail("-r", "--require FILE", "require the library") { |file| ruby_require file }
65d6456c » macournoyer 2008-02-11 * Wrap application in a Rac... 118 opts.on_tail("-D", "--debug", "Set debbuging on") { Logging.debug = true }
119 opts.on_tail("-V", "--trace", "Set tracing on (log raw request/response)") { Logging.trace = true }
120 opts.on_tail("-h", "--help", "Show this message") { puts opts; exit }
121 opts.on_tail('-v', '--version', "Show version") { puts Thin::SERVER; exit }
401ade74 » macournoyer 2008-02-01 Refactoring thin script in ... 122 end
123 end
124
348f6e4d » macournoyer 2008-02-03 Change thin service install... 125 # Parse the options.
be65e98b » macournoyer 2008-02-01 Add specs for Runner and Co... 126 def parse!
127 parser.parse! @argv
348f6e4d » macournoyer 2008-02-03 Change thin service install... 128 @command = @argv.shift
129 @arguments = @argv
be65e98b » macournoyer 2008-02-01 Add specs for Runner and Co... 130 end
348f6e4d » macournoyer 2008-02-03 Change thin service install... 131
401ade74 » macournoyer 2008-02-01 Refactoring thin script in ... 132 # Parse the current shell arguments and run the command.
133 # Exits on error.
134 def run!
348f6e4d » macournoyer 2008-02-03 Change thin service install... 135 if self.class.commands.include?(@command)
be65e98b » macournoyer 2008-02-01 Add specs for Runner and Co... 136 run_command
137 elsif @command.nil?
401ade74 » macournoyer 2008-02-01 Refactoring thin script in ... 138 puts "Command required"
139 puts @parser
140 exit 1
141 else
117e405e » macournoyer 2008-02-02 * Add a script to run thin ... 142 abort "Invalid command: #{@command}"
401ade74 » macournoyer 2008-02-01 Refactoring thin script in ... 143 end
144 end
145
146 # Send the command to the controller: single instance or cluster.
be65e98b » macournoyer 2008-02-01 Add specs for Runner and Co... 147 def run_command
117e405e » macournoyer 2008-02-02 * Add a script to run thin ... 148 load_options_from_config_file! unless CONFIGLESS_COMMANDS.include?(@command)
401ade74 » macournoyer 2008-02-01 Refactoring thin script in ... 149
2772b6e2 » macournoyer 2008-02-02 Set process name to 'thin s... 150 # PROGRAM_NAME is relative to the current directory, so make sure
151 # we store and expand it before changing directory.
152 Command.script = File.expand_path($PROGRAM_NAME)
153
05459cd9 » macournoyer 2008-02-05 thin config --chrdir ... -C... 154 # Change the current directory ASAP so that all relative paths are
155 # relative to this one.
156 Dir.chdir(@options[:chdir]) unless CONFIGLESS_COMMANDS.include?(@command)
3210ef9b » macournoyer 2008-02-02 Make sure chdir option from... 157
117e405e » macournoyer 2008-02-02 * Add a script to run thin ... 158 controller = case
f904fa03 » macournoyer 2008-02-03 Move controllers into their... 159 when cluster? then Controllers::Cluster.new(@options)
160 when service? then Controllers::Service.new(@options)
161 else Controllers::Controller.new(@options)
401ade74 » macournoyer 2008-02-01 Refactoring thin script in ... 162 end
163
117e405e » macournoyer 2008-02-02 * Add a script to run thin ... 164 if controller.respond_to?(@command)
af63af25 » macournoyer 2008-03-13 * Guess which adapter to us... 165 begin
166 controller.send(@command, *@arguments)
167 rescue RunnerError => e
168 abort e.message
169 end
117e405e » macournoyer 2008-02-02 * Add a script to run thin ... 170 else
171 abort "Invalid options for command: #{@command}"
172 end
401ade74 » macournoyer 2008-02-01 Refactoring thin script in ... 173 end
174
175 # +true+ if we're controlling a cluster.
176 def cluster?
22c1acef » macournoyer 2008-05-15 Fix hanging when restarting... 177 @options[:only] || @options[:servers] || @options[:config]
401ade74 » macournoyer 2008-02-01 Refactoring thin script in ... 178 end
179
117e405e » macournoyer 2008-02-02 * Add a script to run thin ... 180 # +true+ if we're acting a as system service.
181 def service?
348f6e4d » macournoyer 2008-02-03 Change thin service install... 182 @options.has_key?(:all) || @command == 'install'
117e405e » macournoyer 2008-02-02 * Add a script to run thin ... 183 end
184
401ade74 » macournoyer 2008-02-01 Refactoring thin script in ... 185 private
186 def load_options_from_config_file!
187 if file = @options.delete(:config)
188 YAML.load_file(file).each { |key, value| @options[key.to_sym] = value }
189 end
190 end
a3a783e2 » macournoyer 2008-04-05 Add --require (-r) option t... 191
192 def ruby_require(file)
193 if File.extname(file) == '.ru'
194 warn 'WARNING: Use the -R option to load a Rack config file'
195 @options[:rackup] = file
196 else
197 require file
198 end
199 end
401ade74 » macournoyer 2008-02-01 Refactoring thin script in ... 200 end
201 end