Class: Raptor::Server

Inherits:
Object
  • Object
show all
Defined in:
lib/raptor/server.rb

Overview

High-performance HTTP server that accepts connections and dispatches them.

Server manages the main accept loop, handling incoming client connections from bound sockets. It uses IO.select for efficient polling and implements automatic load balancing by checking reactor backlog before accepting connections, providing natural backpressure based on system capacity.

Supports TCP, Unix domain, and SSL listeners transparently. TCP_NODELAY is applied only to TCP sockets, and SSL handshakes are performed synchronously before the connection is dispatched.

For HTTP/1.1 connections the first request is parsed inline on the server thread and dispatched directly to the thread pool, falling back to the reactor only when more data is needed. For HTTP/2 connections (negotiated via ALPN) the server sends initial SETTINGS and registers the connection with the reactor for frame processing through the ractor pool.

Examples:

binder = Binder.new(["tcp://0.0.0.0:3000"])
reactor = Reactor.new(thread_pool, ractor_pool, client_options: {})
request = Request.new(app, 3000)
server = Server.new(binder, reactor, thread_pool, request)
server.run
# ... later
server.shutdown

Constant Summary collapse

HTTP_SCHEME =
"http"
HTTPS_SCHEME =
"https"
H2_PROTOCOL =
"h2"

Instance Method Summary collapse

Constructor Details

#initialize(binder, reactor, thread_pool, request) ⇒ void

Creates a new Server instance.

Parameters:

  • binder (Binder)

    the binder managing listening sockets

  • reactor (Reactor)

    the reactor for handling client connections

  • thread_pool (AtomicThreadPool)

    thread pool for application processing

  • request (Request)

    the HTTP/1.1 request handler



55
56
57
58
59
60
61
# File 'lib/raptor/server.rb', line 55

def initialize(binder, reactor, thread_pool, request)
  @binder = binder
  @reactor = reactor
  @thread_pool = thread_pool
  @request = request
  @running = AtomicBoolean.new(true)
end

Instance Method Details

#runThread

Starts the server’s main accept loop in a new thread.

The accept loop polls listening sockets for ready connections and accepts them when system capacity allows. It checks reactor backlog before accepting to prevent overload. This provides natural load balancing across multiple worker processes through backpressure control.

Returns:

  • (Thread)

    the thread running the accept loop



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/raptor/server.rb', line 73

def run
  Thread.new(@binder.listeners, @reactor, @running) do |server_sockets, reactor, running|
    Thread.current.name = self.class.name

    while running.true?
      begin
        ready_servers, _, _ = IO.select(server_sockets, nil, nil, 1)
      rescue IOError, Errno::EBADF
        break
      end

      next unless ready_servers
      next if @reactor.backlog >= (@thread_pool.size * 1.2).ceil

      ready_servers.each do |listener|
        accept_connection(listener, reactor)
      end
    end
  end
end

#shutdownvoid

This method returns an undefined value.

Gracefully shuts down the server.

Stops accepting new connections and closes all listening sockets. The server thread will exit after handling any in-flight accept operations.



102
103
104
105
# File 'lib/raptor/server.rb', line 102

def shutdown
  @running.make_false
  @binder.close
end