Parent

Included Modules

Thin::Controllers::Controller

Controls one Thin server. Allow to start, stop, restart and configure a single thin server.

Attributes

options[RW]

Command line options passed to the thin script

Public Class Methods

new(options) click to toggle source
    # File lib/thin/controllers/controller.rb, line 28
28:       def initialize(options)
29:         @options = options
30:         
31:         if @options[:socket]
32:           @options.delete(:address)
33:           @options.delete(:port)
34:         end
35:       end

Public Instance Methods

config() click to toggle source
     # File lib/thin/controllers/controller.rb, line 109
109:       def config
110:         config_file = @options.delete(:config) || raise(OptionRequired, :config)
111: 
112:         # Stringify keys
113:         @options.keys.each { |o| @options[o.to_s] = @options.delete(o) }
114: 
115:         File.open(config_file, 'w') { |f| f << @options.to_yaml }
116:         log ">> Wrote configuration to #{config_file}"
117:       end
restart() click to toggle source
     # File lib/thin/controllers/controller.rb, line 99
 99:       def restart
100:         raise OptionRequired, :pid unless @options[:pid]
101:         
102:         tail_log(@options[:log]) do
103:           if Server.restart(@options[:pid])
104:             wait_for_file :creation, @options[:pid]
105:           end
106:         end
107:       end
start() click to toggle source
    # File lib/thin/controllers/controller.rb, line 37
37:       def start
38:         # Constantize backend class
39:         @options[:backend] = eval(@options[:backend], TOPLEVEL_BINDING) if @options[:backend]
40:         
41:         server = Server.new(@options[:socket] || @options[:address], # Server detects kind of socket
42:                             @options[:port],                         # Port ignored on UNIX socket
43:                             @options)
44:         
45:         # Set options
46:         server.pid_file                       = @options[:pid]
47:         server.log_file                       = @options[:log]
48:         server.timeout                        = @options[:timeout]
49:         server.maximum_connections            = @options[:max_conns]
50:         server.maximum_persistent_connections = @options[:max_persistent_conns]
51:         server.threaded                       = @options[:threaded]
52:         server.no_epoll                       = @options[:no_epoll] if server.backend.respond_to?(:no_epoll=)
53: 
54:         # ssl support
55:         if @options[:ssl]
56:           server.ssl = true
57:           server.ssl_options = { :private_key_file => @options[:ssl_key_file], :cert_chain_file => @options[:ssl_cert_file], :verify_peer => @options[:ssl_verify] }
58:         end
59: 
60:         # Detach the process, after this line the current process returns
61:         server.daemonize if @options[:daemonize]
62: 
63:         # +config+ must be called before changing privileges since it might require superuser power.
64:         server.config
65:         
66:         server.change_privilege @options[:user], @options[:group] if @options[:user] && @options[:group]
67: 
68:         # If a Rack config file is specified we eval it inside a Rack::Builder block to create
69:         # a Rack adapter from it. Or else we guess which adapter to use and load it.
70:         if @options[:rackup]
71:           server.app = load_rackup_config
72:         else
73:           server.app = load_adapter
74:         end
75: 
76:         # If a prefix is required, wrap in Rack URL mapper
77:         server.app = Rack::URLMap.new(@options[:prefix] => server.app) if @options[:prefix]
78: 
79:         # If a stats URL is specified, wrap in Stats adapter
80:         server.app = Stats::Adapter.new(server.app, @options[:stats]) if @options[:stats]
81: 
82:         # Register restart procedure which just start another process with same options,
83:         # so that's why this is done here.
84:         server.on_restart { Command.run(:start, @options) }
85: 
86:         server.start
87:       end
stop() click to toggle source
    # File lib/thin/controllers/controller.rb, line 89
89:       def stop
90:         raise OptionRequired, :pid unless @options[:pid]
91:       
92:         tail_log(@options[:log]) do
93:           if Server.kill(@options[:pid], @options[:force] ? 0 : (@options[:timeout] || 60))
94:             wait_for_file :deletion, @options[:pid]
95:           end
96:         end
97:       end

Protected Instance Methods

tail(file) click to toggle source

Acts like GNU tail command. Taken from Rails.

     # File lib/thin/controllers/controller.rb, line 142
142:         def tail(file)
143:           cursor = File.exist?(file) ? File.size(file) : 0
144:           last_checked = Time.now
145:           tail_thread = Thread.new do
146:             Thread.pass until File.exist?(file)
147:             File.open(file, 'r') do |f|
148:               loop do
149:                 f.seek cursor
150:                 if f.mtime > last_checked
151:                   last_checked = f.mtime
152:                   contents = f.read
153:                   cursor += contents.length
154:                   print contents
155:                   STDOUT.flush
156:                 end
157:                 sleep 0.1
158:               end
159:             end
160:           end
161:           sleep 1 if File.exist?(file) # HACK Give the thread a little time to open the file
162:           tail_thread
163:         end
tail_log(log_file) click to toggle source

Tail the log file of server number during the execution of the block.

     # File lib/thin/controllers/controller.rb, line 131
131:         def tail_log(log_file)
132:           if log_file
133:             tail_thread = tail(log_file)
134:             yield
135:             tail_thread.kill
136:           else
137:             yield
138:           end
139:         end
wait_for_file(state, file) click to toggle source

Wait for a pid file to either be created or deleted.

     # File lib/thin/controllers/controller.rb, line 121
121:         def wait_for_file(state, file)
122:           Timeout.timeout(@options[:timeout] || 30) do
123:             case state
124:             when :creation then sleep 0.1 until File.exist?(file)
125:             when :deletion then sleep 0.1 while File.exist?(file)
126:             end
127:           end
128:         end

Private Instance Methods

load_adapter() click to toggle source
     # File lib/thin/controllers/controller.rb, line 166
166:         def load_adapter
167:           adapter = @options[:adapter] || Rack::Adapter.guess(@options[:chdir])
168:           log ">> Using #{adapter} adapter"
169:           Rack::Adapter.for(adapter, @options)
170:         rescue Rack::AdapterNotFound => e
171:           raise InvalidOption, e.message
172:         end
load_rackup_config() click to toggle source
     # File lib/thin/controllers/controller.rb, line 174
174:         def load_rackup_config
175:           ENV['RACK_ENV'] = @options[:environment]
176:           case @options[:rackup]
177:           when /\.rb$/
178:             Kernel.load(@options[:rackup])
179:             Object.const_get(File.basename(@options[:rackup], '.rb').capitalize.to_sym)
180:           when /\.ru$/
181:             Rack::Adapter.load(@options[:rackup])
182:           else
183:             raise "Invalid rackup file.  please specify either a .ru or .rb file"
184:           end
185:         end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.