Class: Thin::Runner

Class Thin::Runner < Object

(in files lib/thin/runner.rb )

CLI runner. Parse options and send command to the correct Controller.

Includes

Methods

Public Class commands()

Return all available commands

    # File lib/thin/runner.rb, line 24
24:     def self.commands
25:       commands  = COMMANDS
26:       commands += LINUX_ONLY_COMMANDS if Thin.linux?
27:       commands
28:     end

Public Class new(argv)

    # File lib/thin/runner.rb, line 30
30:     def initialize(argv)
31:       @argv = argv
32:       
33:       # Default options values
34:       @options = {
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,
44:         :require              => []
45:       }
46:       
47:       parse!
48:     end

Public Instance cluster?()

true if we‘re controlling a cluster.

     # File lib/thin/runner.rb, line 183
183:     def cluster?
184:       @options[:only] || @options[:servers] || @options[:config]
185:     end

Public Instance parse!()

Parse the options.

     # File lib/thin/runner.rb, line 129
129:     def parse!
130:       parser.parse! @argv
131:       @command   = @argv.shift
132:       @arguments = @argv
133:     end

Public Instance parser()

     # File lib/thin/runner.rb, line 50
 50:     def parser
 51:       # NOTE: If you add an option here make sure the key in the +options+ hash is the
 52:       # same as the name of the command line option.
 53:       # +option+ keys are used to build the command line to launch other processes,
 54:       # see <tt>lib/thin/command.rb</tt>.
 55:       @parser ||= OptionParser.new do |opts|
 56:         opts.banner = "Usage: thin [options] #{self.class.commands.join('|')}"
 57: 
 58:         opts.separator ""
 59:         opts.separator "Server options:"
 60: 
 61:         opts.on("-a", "--address HOST", "bind to HOST address " +
 62:                                         "(default: #{@options[:address]})")             { |host| @options[:address] = host }
 63:         opts.on("-p", "--port PORT", "use PORT (default: #{@options[:port]})")          { |port| @options[:port] = port.to_i }
 64:         opts.on("-S", "--socket FILE", "bind to unix domain socket")                    { |file| @options[:socket] = file }
 65:         opts.on("-y", "--swiftiply [KEY]", "Run using swiftiply")                       { |key| @options[:swiftiply] = key }
 66:         opts.on("-A", "--adapter NAME", "Rack adapter to use (default: autodetect)",
 67:                                         "(#{Rack::ADAPTERS.map{|(a,b)|a}.join(', ')})") { |name| @options[:adapter] = name }
 68:         opts.on("-R", "--rackup FILE", "Load a Rack config file instead of " +
 69:                                        "Rack adapter")                                  { |file| @options[:rackup] = file }
 70:         opts.on("-c", "--chdir DIR", "Change to dir before starting")                   { |dir| @options[:chdir] = File.expand_path(dir) }
 71:         opts.on(      "--stats PATH", "Mount the Stats adapter under PATH")             { |path| @options[:stats] = path }
 72:         
 73:         opts.separator ""
 74:         opts.separator "Adapter options:"
 75:         opts.on("-e", "--environment ENV", "Framework environment " +                       
 76:                                            "(default: #{@options[:environment]})")      { |env| @options[:environment] = env }
 77:         opts.on(      "--prefix PATH", "Mount the app under PATH (start with /)")       { |path| @options[:prefix] = path }
 78:         
 79:         unless Thin.win? # Daemonizing not supported on Windows
 80:           opts.separator ""
 81:           opts.separator "Daemon options:"
 82:                                                                                       
 83:           opts.on("-d", "--daemonize", "Run daemonized in the background")              { @options[:daemonize] = true }
 84:           opts.on("-l", "--log FILE", "File to redirect output " +                      
 85:                                       "(default: #{@options[:log]})")                   { |file| @options[:log] = file }
 86:           opts.on("-P", "--pid FILE", "File to store PID " +                            
 87:                                       "(default: #{@options[:pid]})")                   { |file| @options[:pid] = file }
 88:           opts.on("-u", "--user NAME", "User to run daemon as (use with -g)")           { |user| @options[:user] = user }
 89:           opts.on("-g", "--group NAME", "Group to run daemon as (use with -u)")         { |group| @options[:group] = group }
 90:                                                                                       
 91:           opts.separator ""
 92:           opts.separator "Cluster options:"                                             
 93:                                                                                       
 94:           opts.on("-s", "--servers NUM", "Number of servers to start")                  { |num| @options[:servers] = num.to_i }
 95:           opts.on("-o", "--only NUM", "Send command to only one server of the cluster") { |only| @options[:only] = only }
 96:           opts.on("-C", "--config FILE", "Load options from config file")               { |file| @options[:config] = file }
 97:           opts.on(      "--all [DIR]", "Send command to each config files in DIR")      { |dir| @options[:all] = dir } if Thin.linux?
 98:         end
 99:         
100:         opts.separator ""
101:         opts.separator "Tuning options:"
102:         
103:         opts.on("-b", "--backend CLASS", "Backend to use, full classname")              { |name| @options[:backend] = name }
104:         opts.on("-t", "--timeout SEC", "Request or command timeout in sec " +            
105:                                        "(default: #{@options[:timeout]})")              { |sec| @options[:timeout] = sec.to_i }
106:         opts.on("-f", "--force", "Force the execution of the command")                  { @options[:force] = true }
107:         opts.on(      "--max-conns NUM", "Maximum number of connections " +
108:                                          "(default: #{@options[:max_conns]})",
109:                                          "Might require sudo to set higher then 1024")  { |num| @options[:max_conns] = num.to_i } unless Thin.win?
110:         opts.on(      "--max-persistent-conns NUM",
111:                                        "Maximum number of persistent connections",
112:                                        "(default: #{@options[:max_persistent_conns]})") { |num| @options[:max_persistent_conns] = num.to_i }
113:         opts.on(      "--threaded", "Call the Rack application in threads " +
114:                                     "[experimental]")                                   { @options[:threaded] = true }
115:         opts.on(      "--no-epoll", "Disable the use of epoll")                         { @options[:no_epoll] = true } if Thin.linux?
116:         
117:         opts.separator ""
118:         opts.separator "Common options:"
119: 
120:         opts.on_tail("-r", "--require FILE", "require the library")                     { |file| @options[:require] << file }
121:         opts.on_tail("-D", "--debug", "Set debbuging on")                               { @options[:debug] = true }
122:         opts.on_tail("-V", "--trace", "Set tracing on (log raw request/response)")      { @options[:trace] = true }
123:         opts.on_tail("-h", "--help", "Show this message")                               { puts opts; exit }
124:         opts.on_tail('-v', '--version', "Show version")                                 { puts Thin::SERVER; exit }
125:       end
126:     end

Public Instance run!()

Parse the current shell arguments and run the command. Exits on error.

     # File lib/thin/runner.rb, line 137
137:     def run!
138:       if self.class.commands.include?(@command)
139:         run_command
140:       elsif @command.nil?
141:         puts "Command required"
142:         puts @parser
143:         exit 1  
144:       else
145:         abort "Unknown command: #{@command}. Use one of #{self.class.commands.join(', ')}"
146:       end
147:     end

Public Instance run_command()

Send the command to the controller: single instance or cluster.

     # File lib/thin/runner.rb, line 150
150:     def run_command
151:       load_options_from_config_file! unless CONFIGLESS_COMMANDS.include?(@command)
152:       
153:       # PROGRAM_NAME is relative to the current directory, so make sure
154:       # we store and expand it before changing directory.
155:       Command.script = File.expand_path($PROGRAM_NAME)
156:       
157:       # Change the current directory ASAP so that all relative paths are
158:       # relative to this one.
159:       Dir.chdir(@options[:chdir]) unless CONFIGLESS_COMMANDS.include?(@command)
160:       
161:       @options[:require].each { |r| ruby_require r }
162:       Logging.debug = @options[:debug]
163:       Logging.trace = @options[:trace]
164:       
165:       controller = case
166:       when cluster? then Controllers::Cluster.new(@options)
167:       when service? then Controllers::Service.new(@options)
168:       else               Controllers::Controller.new(@options)
169:       end
170:       
171:       if controller.respond_to?(@command)
172:         begin
173:           controller.send(@command, *@arguments)
174:         rescue RunnerError => e
175:           abort e.message
176:         end
177:       else
178:         abort "Invalid options for command: #{@command}"
179:       end
180:     end

Public Instance service?()

true if we‘re acting a as system service.

     # File lib/thin/runner.rb, line 188
188:     def service?
189:       @options.has_key?(:all) || @command == 'install'
190:     end