### Home Classes Methods

### In Files

- lib/merb-core/rack/adapter/abstract.rb

### Parent

Object

### Methods

- ::exit_process
- ::new_server
- ::process_title
- ::spawn_worker
- ::start
- ::start_at_port
- ::start_server
- ::stop

### Files

- CHANGELOG
- LICENSE
- README
- TODO

### Class/Module Index

Quicksearch

- Merb
- Merb::AbstractController
- Merb::AcceptType
- Merb::AuthenticationMixin
- Merb::AuthenticationMixin::BasicAuthentication
- Merb::BootLoader
- Merb::BootLoader::AfterAppLoads
- Merb::BootLoader::BackgroundServices
- Merb::BootLoader::BeforeAppLoads
- Merb::BootLoader::BuildFramework
- Merb::BootLoader::ChooseAdapter
- Merb::BootLoader::Cookies
- Merb::BootLoader::Defaults
- Merb::BootLoader::Dependencies
- Merb::BootLoader::DropPidFile
- Merb::BootLoader::LoadClasses
- Merb::BootLoader::Logger
- Merb::BootLoader::MimeTypes
- Merb::BootLoader::MixinSession
- Merb::BootLoader::RackUpApplication
- Merb::BootLoader::ReloadClasses
- Merb::BootLoader::ReloadClasses::TimedExecutor
- Merb::BootLoader::Router
- Merb::BootLoader::SetupSession
- Merb::BootLoader::SetupStubClasses
- Merb::BootLoader::Templates
- Merb::ConditionalGetMixin
- Merb::Config
- Merb::Config::ConfigBlock
- Merb::Const
- Merb::Controller
- Merb::ControllerExceptions
- Merb::ControllerExceptions::Accepted
- Merb::ControllerExceptions::ActionNotFound
- Merb::ControllerExceptions::BadGateway
- Merb::ControllerExceptions::BadRequest
- Merb::ControllerExceptions::Base
- Merb::ControllerExceptions::ClientError
- Merb::ControllerExceptions::Conflict
- Merb::ControllerExceptions::Continue
- Merb::ControllerExceptions::Created
- Merb::ControllerExceptions::ExpectationFailed
- Merb::ControllerExceptions::Forbidden
- Merb::ControllerExceptions::GatewayTimeout
- Merb::ControllerExceptions::Gone
- Merb::ControllerExceptions::HTTPVersionNotSupported
- Merb::ControllerExceptions::Informational
- Merb::ControllerExceptions::InternalServerError
- Merb::ControllerExceptions::LayoutNotFound
- Merb::ControllerExceptions::LengthRequired
- Merb::ControllerExceptions::MethodNotAllowed
- Merb::ControllerExceptions::MovedPermanently
- Merb::ControllerExceptions::MovedTemporarily
- Merb::ControllerExceptions::MultiPartParseError
- Merb::ControllerExceptions::MultipleChoices
- Merb::ControllerExceptions::NoContent
- Merb::ControllerExceptions::NonAuthoritativeInformation
- Merb::ControllerExceptions::NotAcceptable
- Merb::ControllerExceptions::NotFound
- Merb::ControllerExceptions::NotImplemented
- Merb::ControllerExceptions::NotModified
- Merb::ControllerExceptions::OK
- Merb::ControllerExceptions::PartialContent
- Merb::ControllerExceptions::PaymentRequired
- Merb::ControllerExceptions::PreconditionFailed
- Merb::ControllerExceptions::ProxyAuthenticationRequired
- Merb::ControllerExceptions::Redirection
- Merb::ControllerExceptions::RequestEntityTooLarge
- Merb::ControllerExceptions::RequestRangeNotSatisfiable
- Merb::ControllerExceptions::RequestTimeout
- Merb::ControllerExceptions::RequestURITooLarge
- Merb::ControllerExceptions::ResetContent
- Merb::ControllerExceptions::SeeOther
- Merb::ControllerExceptions::ServerError
- Merb::ControllerExceptions::ServiceUnavailable
- Merb::ControllerExceptions::Successful
- Merb::ControllerExceptions::SwitchingProtocols
- Merb::ControllerExceptions::TemplateNotFound
- Merb::ControllerExceptions::TemporaryRedirect
- Merb::ControllerExceptions::Unauthorized
- Merb::ControllerExceptions::UnsupportedMediaType
- Merb::ControllerExceptions::UseProxy
- Merb::ControllerMixin
- Merb::CookieSession
- Merb::CookieSession::CookieOverflow
- Merb::CookieSession::TamperedWithCookie
- Merb::Cookies
- Merb::CookiesMixin
- Merb::CookiesMixin::RequestMixin
- Merb::Counter
- Merb::Dispatcher
- Merb::Dispatcher::DefaultException
- Merb::Dispatcher::DefaultExceptionHelper
- Merb::GlobalHelpers
- Merb::InlineTemplates
- Merb::Logger
- Merb::MemcacheSession
- Merb::MemcacheStore
- Merb::MemorySession
- Merb::MemorySessionStore
- Merb::Parse
- Merb::Plugins
- Merb::Rack
- Merb::Rack::AbstractAdapter
- Merb::Rack::Adapter
- Merb::Rack::Application
- Merb::Rack::ConditionalGet
- Merb::Rack::Console
- Merb::Rack::ContentLength
- Merb::Rack::DeferrableMiddleware
- Merb::Rack::Ebb
- Merb::Rack::EventedMongrel
- Merb::Rack::FastCGI
- Merb::Rack::Handler
- Merb::Rack::Handler::Mongrel
- Merb::Rack::Head
- Merb::Rack::Helpers
- Merb::Rack::Irb
- Merb::Rack::Middleware
- Merb::Rack::Mongrel
- Merb::Rack::PathPrefix
- Merb::Rack::Profiler
- Merb::Rack::Runner
- Merb::Rack::Static
- Merb::Rack::StreamWrapper
- Merb::Rack::SwiftipliedMongrel
- Merb::Rack::Thin
- Merb::Rack::ThinTurbo
- Merb::Rack::Tracer
- Merb::Rack::WEBrick
- Merb::RenderMixin
- Merb::RenderMixin::ClassMethods
- Merb::Request
- Merb::ReservedError
- Merb::Responder
- Merb::ResponderMixin
- Merb::ResponderMixin::ClassMethods
- Merb::ResponderMixin::ContentTypeAlreadySet
- Merb::Router
- Merb::Router::Behavior
- Merb::Router::Behavior::Error
- Merb::Router::Behavior::Proxy
- Merb::Router::CachedProc
- Merb::Router::GenerationError
- Merb::Router::NotCompiledError
- Merb::Router::Resources
- Merb::Router::RouteNotFound
- Merb::Server
- Merb::Session
- Merb::SessionContainer
- Merb::SessionMixin
- Merb::SessionMixin::NoSessionContainer
- Merb::SessionMixin::RequestMixin
- Merb::SessionMixin::RequestMixin::ClassMethods
- Merb::SessionMixin::SessionOverflow
- Merb::SessionStoreContainer
- Merb::System
- Merb::System::PortablePoller
- Merb::Template
- Merb::Template::Erubis
- Merb::Template::Erubis::Mixin
- Merb::Test
- Merb::Test::ControllerHelper
- Merb::Test::Cookie
- Merb::Test::CookieJar
- Merb::Test::ExampleGroup
- Merb::Test::Helpers
- Merb::Test::MakeRequest
- Merb::Test::Matchers
- Merb::Test::MultipartRequestHelper
- Merb::Test::MultipartRequestHelper::FileParam
- Merb::Test::MultipartRequestHelper::Param
- Merb::Test::MultipartRequestHelper::Post
- Merb::Test::RequestHelper
- Merb::Test::RequestHelper::CookieJar
- Merb::Test::RequestHelper::FakeRequest
- Merb::Test::RouteHelper
- Merb::Test::Rspec
- Merb::Test::Rspec::ControllerMatchers
- Merb::Test::Rspec::ControllerMatchers::BeError
- Merb::Test::Rspec::ControllerMatchers::BeRedirect
- Merb::Test::Rspec::ControllerMatchers::Provide
- Merb::Test::Rspec::RouteMatchers
- Merb::Test::Rspec::RouteMatchers::ParameterMatcher
- Merb::Test::Rspec::RouteMatchers::RouteToMatcher
- Merb::Test::ViewHelper
- Merb::Test::WebratHelper
- Merb::Worker
- Erubis
- Erubis::Basic
- Erubis::Basic::Converter
- Erubis::BlockAwareEnhancer
- Erubis::BlockAwareEruby
- Erubis::MEruby
- Spec
- Spec::Matchers
- Spec::Matchers::MatcherDSL
- Spec::Runner
- Spec::Runner::Formatter
- Spec::Runner::Formatter::BaseTextFormatter
- Gem
- Gem::Dependency
- Hpricot
- Hpricot::Elem
- Mongrel
- Mongrel::HttpResponse
- Class
- Exception
- Hash
- Kernel
- MemCache
- Memcached
- Object
- String
- Time

No matching classes.

# Merb::Rack::AbstractAdapter

### Public Class Methods

exit_process(status = 0) click to toggle source

Exit the process with the specified status.

#### Parameters

status<Integer> | The exit code of the process.

:api: private

    # File lib/merb-core/rack/adapter/abstract.rb, line 314
    def self.exit_process(status = 0)
      exit(status)
    end

new_server(port) click to toggle source

This method is designed to be overridden in a rack adapter. It will be called to create a new instance of the server for the adapter to start. The adapter should attempt to bind to a port at this point. This is called from the AbstractAdapter start method.

#### Parameters

port<Integer> | The port the server should listen on

:api: plugin @overridable

    # File lib/merb-core/rack/adapter/abstract.rb, line 68
    def self.new_server(port)
      raise NotImplemented
    end

process_title(whoami, port) click to toggle source

Set the process title.

#### Parameters

whoami<Symbol> | Either :spawner for the master process or :worker for any of the worker

    processes.

port<Integer> | The base port that the app is running on.

:api: private

    # File lib/merb-core/rack/adapter/abstract.rb, line 326
    def self.process_title(whoami, port)
      name = Merb::Config[:name]
      app  = "merb#{" : #{name}" if (name && name != "merb")}"
      max_port  = Merb::Config[:cluster] ? (Merb::Config[:cluster] - 1) : 0
      numbers   = ((whoami != :worker) && (max_port > 0)) ? "#{port}..#{port + max_port}" : port
      file      = Merb::Config[:socket_file] % port if Merb::Config[:socket_file]

      listening_on = if Merb::Config[:socket]
        "socket#{'s' if max_port > 0 && whoami != :worker} #{numbers} "           "#{file ? file : "#{Merb.log_path}/#{name}.#{port}.sock"}"
      else
        "port#{'s' if max_port > 0 && whoami != :worker} #{port}"
      end
      "#{app} : #{whoami} (#{listening_on})"
    end

spawn_worker(port) click to toggle source

Spawn a new worker process at a port.

#### Parameters

port<Integer> | The port to start the worker process on.

:api: private

    # File lib/merb-core/rack/adapter/abstract.rb, line 93
    def self.spawn_worker(port)
      worker_pid = Kernel.fork

      # If we have a worker_pid, we're in the parent.
      if worker_pid.nil?
        # Seed the random number generator
        Kernel.srand

        # Restart the run_later worker, unless we're in the parent or it's alive.
        Merb::Worker.restart unless Merb::Worker.alive?

        # Spawn the worker
        start_at_port(port, @opts)

        throw(:new_worker)
      end

      @pids[port] = worker_pid
      $WORKERS = @pids.values
    end

start(opts={}) click to toggle source

The main start method for bootloaders that support forking. This method launches the adapters which inherit using the new_server and start_server methods. This method should not be overridden in adapters which want to fork.

#### Parameters

opts<Hash> | A hash of options

    socket: the socket to bind to
    port: the port to bind to
    cluster: the number

:api: private

    # File lib/merb-core/rack/adapter/abstract.rb, line 126
    def self.start(opts={})
      @opts = opts
      $WORKERS ||= []
      parent = nil

      @pids = {}
      port = (opts[:socket] || opts[:port]).to_i
      max_port = Merb::Config[:cluster] ? Merb::Config[:cluster] - 1 : 0

      # If we only have a single merb, just start it up and dispense with
      # the spawner/worker setup.
      if max_port == 0
        start_at_port(port)
        return
      end

      $0 = process_title(:spawner, port)

      # For each port, spawn a new worker. The parent will continue in
      # the loop, while the worker will throw :new_worker and be booted
      # out of the loop.
      catch(:new_worker) do
        0.upto(max_port) do |i|
          parent = spawn_worker(port + i)
        end
      end

      # If we're in a worker, we're done. Otherwise, we've completed
      # setting up workers and now need to watch them.
      return unless parent

      # For each worker, set up a thread in the spawner to watch it
      0.upto(max_port) do |i|
        Thread.new do
          catch(:new_worker) do
            loop do
              pid, status = @pids[port + i], nil
              poller = Merb::System::PortablePoller.new(pid)
              begin
                i = 0
                loop do
                  # Watch for the pid to exit.
                  _, status = Process.wait2(pid, Process::WNOHANG)
                  break if status

                  if (i % 120 == 0) && Merb::Config[:max_memory] && poller.memory > Merb::Config[:max_memory]
                    Process.kill("INT", pid)
                    if (Process.kill(0, pid) rescue false)
                      sleep Merb::Config[:hang_time] || 5
                      Process.kill(9, pid)
                      Process.wait2(pid) if (Process.kill(0, pid) rescue false)
                    end

                    status = Struct.new(:exitstatus).new(nil)
                    break
                  end
                  i += 1
                  sleep 0.25
                end

                # If the pid doesn't exist, we want to silently exit instead of
                # raising here.
              rescue SystemCallError => e
              ensure
                # If there was no worker with that PID, the status was non-0
                # (we send back a status of 128 when ABRT is called on a
                # worker, and Merb.fatal! exits with a status of 1), or if
                # Merb is in the process of exiting, *then* don't respawn.
                # Note that processes killed with kill -9 will return no
                # exitstatus, and we respawn them.
                if !status ||
                  (status.exitstatus && status.exitstatus != 0) ||
                  Merb.exiting then
                  Thread.exit
                end
              end

              # Otherwise, respawn the worker, and watch it again.
              spawn_worker(port + i)
            end
          end
        end
      end

      # The spawner process will make it here, and when it does, it should just
      # sleep so it can pick up ctrl-c if it's in console mode.
      sleep

    end

start_at_port(port, opts = @opts) click to toggle source

Fork a server on the specified port and start the app.

#### Parameters

port<Integer> | The port to start the server on
opts<Hash> | The hash of options, defaults to the @opts

    instance variable.

:api: private

    # File lib/merb-core/rack/adapter/abstract.rb, line 224
    def self.start_at_port(port, opts = @opts)
      at_exit do
        Merb::Server.remove_pid(port)
      end

      # If Merb is daemonized, trap INT. If it's not daemonized,
      # we let the master process' ctrl-c control the cluster
      # of workers.
      if Merb::Config[:daemonize]
        Merb.trap('INT') do
          Merb.exiting = true
          stop
          Merb.logger.warn! "Exiting port #{port}\n"
          exit_process
        end
        # If it was not fork_for_class_load, we already set up
        # ctrl-c handlers in the master thread.
      elsif Merb::Config[:fork_for_class_load]
        if Merb::Config[:console_trap]
          Merb::Server.add_irb_trap
        end
      end

      # In daemonized mode or not, support HUPing the process to
      # restart it.
      Merb.trap('HUP') do
        Merb.exiting = true
        stop
        Merb.logger.warn! "Exiting port #{port} on #{Process.pid}\n"
        exit_process
      end

      # ABRTing the process will kill it, and it will not be respawned.
      Merb.trap('ABRT') do
        Merb.exiting = true
        stopped = stop(128)
        Merb.logger.warn! "Exiting port #{port}\n" if stopped
        exit_process(128)
      end

      # Each worker gets its own `ps' name.
      $0 = process_title(:worker, port)

      # Store the PID for this worker
      Merb::Server.store_pid(port)

      Merb::Config[:log_delimiter] = "#{process_title(:worker, port)} ~ "

      Merb.reset_logger!
      Merb.logger.warn!("Starting #{self.name.split("::").last} at port #{port}")

      # If we can't connect to the port, keep trying until we can. Print
      # a warning about this once. Try every 0.25s.
      printed_warning = false
      loop do
        begin
          # Call the adapter's new_server method, which should attempt
          # to bind to a port.
          new_server(port)
        rescue Errno::EADDRINUSE => e
          if Merb::Config[:bind_fail_fatal]
            Merb.fatal! "Could not bind to #{port}. It was already in use", e
          end

          unless printed_warning
            Merb.logger.warn! "Port #{port} is in use, "                  "Waiting for it to become available."
            printed_warning = true
          end

          sleep 0.25
          next
        end
        break
      end

      Merb.logger.warn! "Successfully bound to port #{port}"

      Merb::Server.change_privilege

      # Call the adapter's start_server method.
      start_server
    end

start_server() click to toggle source

This method is designed to be overridden in a rack adapter. It will be called to start a server created with the new_server method. This is called from the AbstractAdapter start method.

:api: plugin @overridable

    # File lib/merb-core/rack/adapter/abstract.rb, line 54
    def self.start_server
      raise NotImplemented
    end

stop(status) click to toggle source

This method is designed to be overridden in a rack adapter. It will be called to stop the adapter server.

#### Parameters

status<Integer> | The exit status the adapter should exit with.

#### Returns

Boolean | True if the server was properly stopped.

:api: plugin @overridable

    # File lib/merb-core/rack/adapter/abstract.rb, line 83
    def self.stop(status)
      raise NotImplemented
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.