Object
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 40 def initialize(app, events=Events::DEFAULT) @app = app @events = events @check, @notify = IO.pipe @ios = [@check] @status = :stop @min_threads = 0 @max_threads = 16 @auto_trim_time = 1 @thread = nil @thread_pool = nil @persistent_timeout = PERSISTENT_TIMEOUT @persistent_check, @persistent_wakeup = IO.pipe @first_data_timeout = FIRST_DATA_TIMEOUT @unix_paths = [] @proto_env = { "rack.version".freeze => Rack::VERSION, "rack.errors".freeze => events.stderr, "rack.multithread".freeze => true, "rack.multiprocess".freeze => false, "rack.run_once".freeze => false, "SCRIPT_NAME".freeze => ENV['SCRIPT_NAME'] || "", # Rack blows up if this is an empty string, and Rack::Lint # blows up if it's nil. So 'text/plain' seems like the most # sensible default value. "CONTENT_TYPE".freeze => "text/plain", "QUERY_STRING".freeze => "", SERVER_PROTOCOL => HTTP_11, SERVER_SOFTWARE => PUMA_VERSION, GATEWAY_INTERFACE => CGI_VER } @envs = {} ENV['RACK_ENV'] ||= "development" end
# File lib/puma/server.rb, line 133 def add_ssl_listener(host, port, ctx, optimize_for_latency=true, backlog=1024) s = TCPServer.new(host, port) if optimize_for_latency s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) end s.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR, true) s.listen backlog ssl = OpenSSL::SSL::SSLServer.new(s, ctx) env = @proto_env.dup env[HTTPS_KEY] = HTTPS @envs[ssl] = env @ios << ssl s end
Tell the server to listen on host host, port port. If optimize_for_latency is true (the default) then clients connecting will be optimized for latency over throughput.
backlog indicates how many unaccepted connections the kernel should allow to accumulate before returning connection refused.
# File lib/puma/server.rb, line 116 def add_tcp_listener(host, port, optimize_for_latency=true, backlog=1024) s = TCPServer.new(host, port) if optimize_for_latency s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) end s.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR, true) s.listen backlog @ios << s s end
Tell the server to listen on path as a UNIX domain socket.
# File lib/puma/server.rb, line 158 def add_unix_listener(path, umask=nil) @unix_paths << path # Let anyone connect by default umask ||= 0 begin old_mask = File.umask(umask) s = UNIXServer.new(path) @ios << s ensure File.umask old_mask end s end
# File lib/puma/server.rb, line 184 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 94 def cork_socket(socket) socket.setsockopt(6, 3, 1) if socket.kind_of? TCPSocket end
# File lib/puma/server.rb, line 239 def handle_servers begin check = @check sockets = @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 c = Client.new sock.accept, @envs.fetch(sock, @proto_env) pool << c 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 @reactor.clear! if @status == :restart @reactor.shutdown graceful_shutdown if @status == :stop ensure unless @status == :restart @ios.each { |i| i.close } @unix_paths.each { |i| File.unlink i } end end end
# File lib/puma/server.rb, line 127 def inherit_tcp_listener(host, port, fd) s = TCPServer.for_fd(fd) @ios << s s end
# File lib/puma/server.rb, line 175 def inherit_unix_listener(path, fd) @unix_paths << path s = UNIXServer.for_fd fd @ios << s s end
# File lib/puma/server.rb, line 150 def inherited_ssl_listener(fd, ctx) s = TCPServer.for_fd(fd) @ios << OpenSSL::SSL::SSLServer.new(s, ctx) s 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 198 def run(background=true) BasicSocket.do_not_reverse_lookup = true @status = :run @thread_pool = ThreadPool.new(@min_threads, @max_threads) do |client| process_now = false begin process_now = client.eagerly_finish rescue HttpParserError => e client.close @events.parse_error self, client.env, e rescue IOError client.close else if process_now process_client client 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 if background @thread = Thread.new { handle_servers } return @thread else handle_servers end end
Generated with the Darkfish Rdoc Generator 2.