Class: Thin::Server

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Daemonizable, Logging
Defined in:
lib/thin/server.rb

Overview

The uterly famous Thin HTTP server. It listen for incoming request through a given backend and forward all request to app.

TCP server

Create a new TCP server on bound to host:port by specifiying host and port as the first 2 arguments.

Thin::Server.start('0.0.0.0', 3000, app)

UNIX domain server

Create a new UNIX domain socket bound to socket file by specifiying a filename as the first argument. Eg.: /tmp/thin.sock. If the first argument contains a / it will be assumed to be a UNIX socket.

Thin::Server.start('/tmp/thin.sock', app)

Using a custom backend

You can implement your own way to connect the server to its client by creating your own Backend class and pass it as the :backend option.

Thin::Server.start('galaxy://faraway', 1345, app, :backend => Thin::Backends::MyFancyBackend)

Rack application (app)

All requests will be processed through app that must be a valid Rack adapter. A valid Rack adapter (application) must respond to call(env#Hash) and return an array of [status, headers, body].

Building an app in place

If a block is passed, a Rack::Builder instance will be passed to build the app. So you can do cool stuff like this:

Thin::Server.start('0.0.0.0', 3000) do
  use Rack::CommonLogger
  use Rack::ShowExceptions
  map "/lobster" do
    use Rack::Lint
    run Rack::Lobster.new
  end
end

Controlling with signals

  • QUIT: Gracefull shutdown (see Server#stop)

  • INT and TERM: Force shutdown (see Server#stop!)

Disable signals by passing :signals => false

Constant Summary collapse

DEFAULT_TIMEOUT =

Default values

30
DEFAULT_HOST =

sec

'0.0.0.0'
DEFAULT_PORT =
3000
DEFAULT_MAXIMUM_CONNECTIONS =
1024
DEFAULT_MAXIMUM_PERSISTENT_CONNECTIONS =
100

Instance Attribute Summary collapse

Attributes included from Daemonizable

#log_file, #pid_file

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Daemonizable

#change_privilege, #daemonize, included, #on_restart, #pid, #restart

Methods included from Logging

#debug, debug, debug?, #log, log, #log_error, log_error, #silent, #silent=, silent?, #trace, trace, trace?

Constructor Details

#initialize(*args, &block) ⇒ Server

Returns a new instance of Server.



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/thin/server.rb', line 97

def initialize(*args, &block)
  host, port, options = DEFAULT_HOST, DEFAULT_PORT, {}

  # Guess each parameter by its type so they can be
  # received in any order.
  args.each do |arg|
    case arg
    when Fixnum, /^\d+$/ then port    = arg.to_i
    when String          then host    = arg
    when Hash            then options = arg
    else
      @app = arg if arg.respond_to?(:call)
    end
  end

  # Set tag if needed
  self.tag = options[:tag]

  # Try to intelligently select which backend to use.
  @backend = select_backend(host, port, options)

  load_cgi_multipart_eof_fix

  @backend.server = self

  # Set defaults
  @backend.maximum_connections            = DEFAULT_MAXIMUM_CONNECTIONS
  @backend.maximum_persistent_connections = DEFAULT_MAXIMUM_PERSISTENT_CONNECTIONS
  @backend.timeout                        = DEFAULT_TIMEOUT

  # Allow using Rack builder as a block
  @app = Rack::Builder.new(&block).to_app if block

  # If in debug mode, wrap in logger adapter
  @app = Rack::CommonLogger.new(@app) if Logging.debug?

  setup_signals unless options[:signals].class == FalseClass
end

Instance Attribute Details

#appObject

Application (Rack adapter) called with the request that produces the response.



61
62
63
# File 'lib/thin/server.rb', line 61

def app
  @app
end

#backendObject

Backend handling the connections to the clients.



67
68
69
# File 'lib/thin/server.rb', line 67

def backend
  @backend
end

#tagObject

A tag that will show in the process listing



64
65
66
# File 'lib/thin/server.rb', line 64

def tag
  @tag
end

Class Method Details

.start(*args, &block) ⇒ Object

Lil’ shortcut to turn this:

Server.new(...).start

into this:

Server.start(...)


144
145
146
# File 'lib/thin/server.rb', line 144

def self.start(*args, &block)
  new(*args, &block).start!
end

Instance Method Details

#after_daemonizeObject

deamonizing kills our HUP signal, so we set them again



221
222
223
# File 'lib/thin/server.rb', line 221

def after_daemonize
  setup_signals
end

#configObject

Configure the server

The process might need to have superuser privilege to configure server with optimal options.



202
203
204
# File 'lib/thin/server.rb', line 202

def config
  @backend.config
end

#nameObject Also known as: to_s

Name of the server and type of backend used. This is also the name of the process in which Thin is running as a daemon.



208
209
210
# File 'lib/thin/server.rb', line 208

def name
  "thin server (#{@backend})" + (tag ? " [#{tag}]" : "")
end


225
226
227
228
229
230
# File 'lib/thin/server.rb', line 225

def print_status
  puts "THIN_STATUS - '#{DateTime.now.to_s}' - '#{@backend.size}' - '#{@backend}' "
  @backend.connections_list.each do |c|
    puts "THIN_CONNECTION: #{c.request.env['REQUEST_METHOD']} #{c.request.env['REQUEST_URI']}" unless c.request.env['REQUEST_METHOD'].nil? ||  c.request.env['REQUEST_URI'].nil?
  end
end

#reopen_logObject

Reopen log file.

Reopen the log file and redirect STDOUT and STDERR to it.



192
193
194
195
196
197
# File 'lib/thin/server.rb', line 192

def reopen_log
  return unless log_file
  file = File.expand_path(log_file)
  log ">> Reopening log file: #{file}"
  Daemonize.redirect_io(file)
end

#running?Boolean

Return true if the server is running and ready to receive requests. Note that the server might still be running and return false when shuting down and waiting for active connections to complete.

Returns:

  • (Boolean)


216
217
218
# File 'lib/thin/server.rb', line 216

def running?
  @backend.running?
end

#startObject Also known as: start!

Start the server and listen for connections.

Raises:

  • (ArgumentError)


149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/thin/server.rb', line 149

def start
  raise ArgumentError, 'app required' unless @app

  log   ">> Thin web server (v#{VERSION::STRING} codename #{VERSION::CODENAME})"
  debug ">> Debugging ON"
  trace ">> Tracing ON"

  log ">> Maximum connections set to #{@backend.maximum_connections}"
  log ">> Listening on #{@backend}, CTRL+C to stop"

  @backend.start
end

#stopObject

Gracefull shutdown

Stops the server after processing all current connections. As soon as this method is called, the server stops accepting new requests and wait for all current connections to finish. Calling twice is the equivalent of calling stop!.



168
169
170
171
172
173
174
175
176
177
178
# File 'lib/thin/server.rb', line 168

def stop
  if running?
    @backend.stop
    unless @backend.empty?
      log ">> Waiting for #{@backend.size} connection(s) to finish, " +
             "can take up to #{timeout} sec, CTRL+C to stop now"
    end
  else
    stop!
  end
end

#stop!Object

Force shutdown

Stops the server closing all current connections right away. This doesn’t wait for connection to finish their work and send data. All current requests will be dropped.



184
185
186
187
188
# File 'lib/thin/server.rb', line 184

def stop!
  log ">> Stopping ..."

  @backend.stop!
end