Create a server for the rack app app.
events is an object which will be called when certain error events occur to be handled. See Puma::Events for the list of current methods to implement.
Server#run returns a thread that you can join on to wait for the server to do it's work.
# File lib/puma/server.rb, line 52 def initialize(app, events=Events.stdio, options={}) @app = app @events = events @check, @notify = Puma::Util.pipe @status = :stop @min_threads = 0 @max_threads = 16 @auto_trim_time = 1 @thread = nil @thread_pool = nil @persistent_timeout = PERSISTENT_TIMEOUT @binder = Binder.new(events) @own_binder = true @first_data_timeout = FIRST_DATA_TIMEOUT @leak_stack_on_error = true @options = options ENV['RACK_ENV'] ||= "development" @mode = :http end
# File lib/puma/server.rb, line 126 def backlog @thread_pool and @thread_pool.backlog end
6 == Socket::IPPROTO_TCP 3 == TCP_CORK 1/0 == turn on/off
# File lib/puma/server.rb, line 105 def cork_socket(socket) begin socket.setsockopt(6, 3, 1) if socket.kind_of? TCPSocket rescue IOError, SystemCallError end end
# File lib/puma/server.rb, line 280 def handle_servers begin check = @check sockets = [check] + @binder.ios pool = @thread_pool while @status == :run begin ios = IO.select sockets ios.first.each do |sock| if sock == check break if handle_check else begin if io = sock.accept_nonblock c = Client.new io, @binder.env(sock) pool << c end rescue SystemCallError end end end rescue Errno::ECONNABORTED # client closed the socket even before accept client.close rescue nil rescue Object => e @events.unknown_error self, e, "Listen loop" end end @events.fire :state, @status graceful_shutdown if @status == :stop || @status == :restart @reactor.clear! if @status == :restart @reactor.shutdown rescue Exception => e STDERR.puts "Exception handling servers: #{e.message} (#{e.class})" STDERR.puts e.backtrace ensure @check.close @notify.close if @status != :restart and @own_binder @binder.close end end @events.fire :state, :done end
# File lib/puma/server.rb, line 173 def handle_servers_lopez_mode begin check = @check sockets = [check] + @binder.ios pool = @thread_pool while @status == :run begin ios = IO.select sockets ios.first.each do |sock| if sock == check break if handle_check else begin if io = sock.accept_nonblock c = Client.new io, nil pool << c end rescue SystemCallError end end end rescue Errno::ECONNABORTED # client closed the socket even before accept client.close rescue nil rescue Object => e @events.unknown_error self, e, "Listen loop" end end @events.fire :state, @status graceful_shutdown if @status == :stop || @status == :restart rescue Exception => e STDERR.puts "Exception handling servers: #{e.message} (#{e.class})" STDERR.puts e.backtrace ensure @check.close @notify.close if @status != :restart and @own_binder @binder.close end end @events.fire :state, :done end
# File lib/puma/server.rb, line 89 def inherit_binder(bind) @binder = bind @own_binder = false end
Runs the server.
If background is true (the default) then a thread is spun up in the background to handle requests. Otherwise requests are handled synchronously.
# File lib/puma/server.rb, line 227 def run(background=true) BasicSocket.do_not_reverse_lookup = true @events.fire :state, :booting @status = :run if @mode == :tcp return run_lopez_mode(background) end @thread_pool = ThreadPool.new(@min_threads, @max_threads, IOBuffer) do |client, buffer| process_now = false begin process_now = client.eagerly_finish rescue HttpParserError => e client.write_400 client.close @events.parse_error self, client.env, e rescue ConnectionError client.close else if process_now process_client client, buffer else client.set_timeout @first_data_timeout @reactor.add client end end end @reactor = Reactor.new self, @thread_pool @reactor.run_in_thread if @auto_trim_time @thread_pool.auto_trim!(@auto_trim_time) end @events.fire :state, :running if background @thread = Thread.new { handle_servers } return @thread else handle_servers end end
Lopez Mode == raw tcp apps
# File lib/puma/server.rb, line 136 def run_lopez_mode(background=true) @thread_pool = ThreadPool.new(@min_threads, @max_threads, Hash) do |client, tl| io = client.to_io addr = io.peeraddr.last if addr.empty? # Set unix socket addrs to localhost addr = "127.0.0.1:0" else addr = "#{addr}:#{io.peeraddr[1]}" end env = { 'thread' => tl, REMOTE_ADDR => addr } begin @app.call env, client.to_io rescue Object => e STDERR.puts "! Detected exception at toplevel: #{e.message} (#{e.class})" STDERR.puts e.backtrace end client.close unless env['detach'] end @events.fire :state, :running if background @thread = Thread.new { handle_servers_lopez_mode } return @thread else handle_servers_lopez_mode end end
# File lib/puma/server.rb, line 130 def running @thread_pool and @thread_pool.spawned end
Generated with the Darkfish Rdoc Generator 2.