Class: Thin::Server

### Home Classes Methods

### In Files

- lib/thin/server.rb

### Parent

Object

### Methods

- ::new
- ::start
- #config
- #handle_signals
- #load_cgi_multipart_eof_fix
- #name
- #reopen_log
- #running?
- #select_backend
- #setup_signals
- #start
- #start!
- #stop
- #stop!
- #to_s

### Included Modules

- Thin::Logging
- Thin::Daemonizable

### Class/Module Index

Quicksearch

- Thin
- Thin::Backends
- Thin::Backends::Base
- Thin::Backends::SwiftiplyClient
- Thin::Backends::TcpServer
- Thin::Backends::UnixServer
- Thin::Command
- Thin::Connection
- Thin::Controllers
- Thin::Controllers::Cluster
- Thin::Controllers::Controller
- Thin::Controllers::Service
- Thin::Daemonizable
- Thin::Daemonizable::ClassMethods
- Thin::Headers
- Thin::InvalidOption
- Thin::InvalidRequest
- Thin::Logging
- Thin::Logging::SimpleFormatter
- Thin::OptionRequired
- Thin::PidFileExist
- Thin::PidFileNotFound
- Thin::PlatformNotSupported
- Thin::Request
- Thin::Response
- Thin::RestartTimeout
- Thin::Runner
- Thin::RunnerError
- Thin::Server
- Thin::Stats
- Thin::Stats::Adapter
- Thin::SwiftiplyConnection
- Thin::UnixConnection
- Rack
- Rack::Adapter
- Rack::Adapter::Rails
- Rack::Adapter::Rails::CGIWrapper
- Rack::Adapter::Rails::CgiApp
- Rack::AdapterNotFound
- Process

No matching classes.

# Thin::Server

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

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

- TERM & QUIT calls `stop` to shutdown gracefully.

- HUP calls `restart` to ... surprise, restart!

- USR1 reopen log files.

Signals are processed at one second intervals. Disable signals by passing `:signals => false`.

### Constants

DEFAULT_HOST
DEFAULT_MAXIMUM_CONNECTIONS
DEFAULT_MAXIMUM_PERSISTENT_CONNECTIONS
DEFAULT_PORT
DEFAULT_TIMEOUT

  Default values

### Attributes

app[RW]

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

backend[RW]

Backend handling the connections to the clients.

tag[RW]

A tag that will show in the process listing

### Public Class Methods

new(*args, &block) click to toggle source

    # File lib/thin/server.rb, line 100
    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 = options[:signals] != false
    end

start(*args, &block) click to toggle source

Lil' shortcut to turn this:

    Server.new(...).start

into this:

    Server.start(...)

    # File lib/thin/server.rb, line 147
    def self.start(*args, &block)
      new(*args, &block).start!
    end

### Public Instance Methods

config() click to toggle source

## Configure the server

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

    # File lib/thin/server.rb, line 211
    def config
      @backend.config
    end

name() click to toggle source

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.

    # File lib/thin/server.rb, line 217
    def name
      "thin server (#{@backend})" + (tag ? " [#{tag}]" : "")
    end

Also aliased as: to_s
reopen_log() click to toggle source

## Reopen log file.

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

    # File lib/thin/server.rb, line 201
    def reopen_log
      return unless log_file
      file = File.expand_path(log_file)
      log_info "Reopening log file: #{file}"
      Daemonize.redirect_io(file)
    end

running?() click to toggle source

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.

    # File lib/thin/server.rb, line 225
    def running?
      @backend.running?
    end

start() click to toggle source

Start the server and listen for connections.

    # File lib/thin/server.rb, line 152
    def start
      raise ArgumentError, 'app required' unless @app

      log_info  "Thin web server (v#{VERSION::STRING} codename #{VERSION::CODENAME})"
      log_debug "Debugging ON"
      trace     "Tracing ON"

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

      @backend.start { setup_signals if @setup_signals }
    end

Also aliased as: start!
start!() click to toggle source
Alias for: start
stop() click to toggle source

## 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!`.

    # File lib/thin/server.rb, line 171
    def stop
      if running?
        @backend.stop
        unless @backend.empty?
          log_info "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!() click to toggle source

## 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.

    # File lib/thin/server.rb, line 187
    def stop!
      if @backend.started_reactor?
        log_info "Stopping ..."
      else
        log_info "Stopping Thin ..."
        log_info "Thin was started inside an existing EventMachine.run block."
        log_info "Call `EventMachine.stop` to stop the reactor and quit the process."
      end

      @backend.stop!
    end

to_s() click to toggle source
Alias for: name

### Protected Instance Methods

handle_signals() click to toggle source

    # File lib/thin/server.rb, line 247
    def handle_signals
      case @signal_queue.shift
      when 'INT'
        stop!
      when 'TERM', 'QUIT'
        stop
      when 'HUP'
        restart
      when 'USR1'
        reopen_log
      end
      EM.next_tick { handle_signals } unless @signal_queue.empty?
    end

load_cgi_multipart_eof_fix() click to toggle source

Taken from Mongrel cgi_multipart_eof_fix Ruby 1.8.5 has a security bug in cgi.rb, we need to patch it.

    # File lib/thin/server.rb, line 277
    def load_cgi_multipart_eof_fix
      version = RUBY_VERSION.split('.').map { |i| i.to_i }

      if version[0] <= 1 && version[1] <= 8 && version[2] <= 5 && RUBY_PLATFORM !~ /java/
        begin
          require 'cgi_multipart_eof_fix'
        rescue LoadError
          log_error "Ruby 1.8.5 is not secure please install cgi_multipart_eof_fix:"
          log_error "gem install cgi_multipart_eof_fix"
        end
      end
    end

select_backend(host, port, options) click to toggle source

    # File lib/thin/server.rb, line 261
    def select_backend(host, port, options)
      case
      when options.has_key?(:backend)
        raise ArgumentError, ":backend must be a class" unless options[:backend].is_a?(Class)
        options[:backend].new(host, port, options)
      when options.has_key?(:swiftiply)
        Backends::SwiftiplyClient.new(host, port, options)
      when host.include?('/')
        Backends::UnixServer.new(host)
      else
        Backends::TcpServer.new(host, port)
      end
    end

setup_signals() click to toggle source

    # File lib/thin/server.rb, line 230
    def setup_signals
      # Queue up signals so they are processed in non-trap context
      # using a EM timer.
      @signal_queue ||= []

      %( INT TERM ).each do |signal|
        trap(signal) { @signal_queue.push signal }
      end
      # *nix only signals
      %( QUIT HUP USR1 ).each do |signal|
        trap(signal) { @signal_queue.push signal }
      end unless Thin.win?

      # Signals are processed at one second intervals.
      @signal_timer ||= EM.add_periodic_timer(1) { handle_signals }
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.