class ObjectFramework::HTTP::Server
Application lifecycle module serving HTTP/1.1 on a dispatcher and one new thread per admitted request. Keep-alive requests execute sequentially. Install with Application#install before startup; the application owns listener startup, cooperative shutdown, and controller validation.
Attributes
Public Class Methods
Source
# File lib/object_framework/http/server.rb, line 27 def initialize(application:, router:, host: "127.0.0.1", port: 0, name: :http, parser: Parser.new, presenter: JSONPresenter.new, problem_presenter: nil, max_requests: 128, max_connections: 1024, header_timeout: 10, body_timeout: 30, execution_timeout: 30, idle_timeout: 30, write_timeout: 30, shutdown_timeout: 5, tls_context: nil, writer_factory: ->(reader) { Writer.new(reader:) }) @application, @router, @host, @port, @name = application, router, host, port, name @parser, @presenter, @problem_presenter = parser, presenter, problem_presenter @max_requests, @max_connections = max_requests, max_connections @header_timeout, @body_timeout, @execution_timeout = header_timeout, body_timeout, execution_timeout @idle_timeout, @write_timeout, @shutdown_timeout = idle_timeout, write_timeout, shutdown_timeout @tls_context, @writer_factory = tls_context, writer_factory @mutex, @workers, @admitted_count = Mutex.new, {}, 0 @completed = Queue.new @connections, @waiting = {}.compare_by_identity, {}.compare_by_identity end
Configures admission limits and timeouts in seconds. port zero lets the OS assign a port, available through port after startup. tls_context is an optional OpenSSL context with application-provided certificate and private key. Execution cancellation is cooperative.
Public Instance Methods
Source
# File lib/object_framework/http/server.rb, line 79 def active_count; @mutex.synchronize { @workers.size }; end
Source
# File lib/object_framework/http/server.rb, line 80 def admitted_count; @mutex.synchronize { @admitted_count }; end
Source
# File lib/object_framework/http/server.rb, line 46 def configure(application) HTTP.register_errors(application.errors) @problem_presenter ||= ProblemPresenter.new(registry: application.errors) end
Source
# File lib/object_framework/http/server.rb, line 81 def connection_count; @connections.size; end
Source
# File lib/object_framework/http/server.rb, line 65 def start @listener = TCPServer.new(@host, @port) @port = @listener.local_address.ip_port @wake_reader, @wake_writer = IO.pipe @running = true @dispatcher = Thread.new { dispatch } self rescue Exception @listener&.close @wake_reader&.close @wake_writer&.close raise end
Source
# File lib/object_framework/http/server.rb, line 83 def stop return unless @dispatcher @running = false wake @dispatcher.join workers = @mutex.synchronize do @workers.each_value { |context, connection| context.cancellation.cancel; connection.close } @workers.keys end deadline = Timing.now + @shutdown_timeout workers.each { |thread| thread.join([deadline - Timing.now, 0].max) } @wake_reader.close @wake_writer.close @dispatcher = nil end
Source
# File lib/object_framework/http/server.rb, line 51 def validate! @router.validate! unless [@max_requests, @max_connections].all? { |value| value.is_a?(Integer) && value.positive? } raise ConfigurationError, "Admission limits must be positive integers" end unless [@header_timeout, @body_timeout, @execution_timeout, @idle_timeout, @write_timeout, @shutdown_timeout].all? { |value| value.is_a?(Numeric) && value.positive? } raise ConfigurationError, "HTTP timeouts must be positive" end if @tls_context raise ConfigurationError, "TLS requires an application certificate and private key" unless @tls_context.cert && @tls_context.key @tls_context.setup end end