0
- # The Thin HTTP server used to served request.
0
- # It listen for incoming request on a given port
0
+ # The uterly famous Thin HTTP server.
0
+ # It listen for incoming request through a given connector
0
# and forward all request to +app+.
0
- # Based on HTTP 1.1 protocol specs:
0
- # http://www.w3.org/Protocols/rfc2616/rfc2616.html
0
+ # Create a new TCP server on bound to <tt>host:port</tt> by specifiying +host+
0
+ # and +port+ as the first 2 arguments.
0
+ # Thin::Server.start('0.0.0.0', 3000, app)
0
+ # == UNIX domain server
0
+ # Create a new UNIX domain socket bound to +socket+ file by specifiying a filename
0
+ # as the first argument. Eg.: /tmp/thin.sock. If the first argument contains a <tt>/</tt>
0
+ # it will be assumed to be a UNIX socket.
0
+ # Thin::Server.start('/tmp/thin.sock', nil, app)
0
+ # == Using a custom connector
0
+ # You can implement your own way to connect the server to its client by creating your
0
+ # own Thin::Connectors::Connector class and pass it as the first argument.
0
+ # connector = Thin::Connectors::MyFancyConnector.new('galaxy://faraway:1345')
0
+ # Thin::Server.start(connector, nil, app)
0
+ # == Rack application (+app+)
0
+ # All requests will be processed through +app+ that must be a valid Rack adapter.
0
+ # A valid Rack adapter (application) must respond to <tt>call(env#Hash)</tt> and
0
+ # return an array of <tt>[status, headers, body]</tt>.
0
+ # == Building an app in place
0
+ # If a block is passed, a <tt>Rack::Builder</tt> instance
0
+ # will be passed to build the +app+. So you can do cool stuff like this:
0
+ # Thin::Server.start('0.0.0.0', 3000) do
0
+ # use Rack::CommonLogger
0
+ # use Rack::ShowExceptions
0
+ # run Rack::Lobster.new
0
- # App called with the request that produces the response.
0
+ # Application (Rack adapter) called with the request that produces the response.
0
# Connector handling the connections to the clients.
0
attr_accessor :connector
0
- # Maximum time for incoming data to arrive
0
+ # Maximum number of seconds for incoming data to arrive before the connection
0
def_delegators :@connector, :timeout, :timeout=
0
# Address and port on which the server is listening for connections.
0
@@ -25,41 +62,40 @@ module Thin
0
# UNIX domain socket on which the server is listening for connections.
0
def_delegator :@connector, :socket
0
- # Creates a new server bound to <tt>host:port</tt>
0
- # or to +socket+ that will pass request to +app+.
0
- # If +host_or_socket+ contains a <tt>/</tt> it is assumed
0
- # to be a UNIX domain socket filename.
0
- # If a block is passed, a <tt>Rack::Builder</tt> instance
0
- # will be passed to build the +app+.
0
- # Server.new '0.0.0.0', 3000 do
0
- # use Rack::CommonLogger
0
- # use Rack::ShowExceptions
0
- # run Rack::Lobster.new
0
- def initialize(host_or_socket, port=3000, app=nil, &block)
0
- if host_or_socket.include?('/')
0
- @connector = Connectors::UnixServer.new(host_or_socket)
0
- @connector = Connectors::TcpServer.new(host_or_socket, port.to_i)
0
+ def initialize(host_or_socket_or_connector, port=3000, app=nil, &block)
0
+ # Try to intelligently select which connector to use.
0
+ when host_or_socket_or_connector.is_a?(Connectors::Connector)
0
+ host_or_socket_or_connector
0
+ when host_or_socket_or_connector.include?('/')
0
+ Connectors::UnixServer.new(host_or_socket_or_connector)
0
+ Connectors::TcpServer.new(host_or_socket_or_connector, port.to_i)
0
@connector.server = self
0
+ # Allow using Rack builder as a block
0
@app = Rack::Builder.new(&block).to_app if block
0
+ # Lil' shortcut to turn this:
0
+ # Server.new(...).start
0
def self.start(*args, &block)
0
new(*args, &block).start!
0
- # Start the server and listen for connections
0
+ # Start the server and listen for connections.
0
+ # Also register signals:
0
+ # * INT calls +stop+ to shutdown gracefully.
0
+ # * TERM calls <tt>stop!</tt> to force shutdown.
0
raise ArgumentError, 'app required' unless @app
0
@@ -73,19 +109,19 @@ module Thin
0
log ">> Listening on #{@connector}, CTRL+C to stop"
0
EventMachine.run { @connector.connect }
0
+ # == Gracefull shutdown.
0
# Stops the server after processing all current connections.
0
+ # As soon as this method is called, the server stops accepting
0
+ # new requests and wait for all current connections to finish.
0
# Calling twice is the equivalent of calling <tt>stop!</tt>.
0
- return unless running?
0
# Do not accept anymore connection
0
@@ -94,16 +130,19 @@ module Thin
0
# Still some connections running, schedule a check later
0
EventMachine.add_periodic_timer(1) { wait_for_connections_and_stop }
0
- # Stops the server closing all current connections
0
+ # Stops the server closing all current connections right away.
0
+ # This doesn't wait for connection to finish their work and send data.
0
+ # All current requests will be dropped.
0
- return unless running?
0
- @connections.each { |connection| connection.close_connection }
0
+ @connector.close_connections
0
@@ -114,8 +153,11 @@ module Thin
0
+ # Return +true+ if the server is running and ready to receive requests.
0
+ # Note that the server might still be running and return +false+ when
0
+ # shuting down and waiting for active connections to complete.
Comments
No one has commented yet.