HttpFrontend
struct HttpFrontend[H: Handler & Copyable]Dynamic-handler HTTP frontend for the multicore scheduler.
Carries the per-worker HTTP state (handler, request config, HTTP/2 settings, auto-protocol toggle) and dispatches into one of three reactor entry points per accepted connection:
- io_uring buffer-ring path (Linux +
use_bufring): :func:run_uring_bufring_reactor_loop_shared. Signalled to the scheduler via :meth:requires_per_worker_listenerso each worker gets its own SO_REUSEPORT listener. - Unified HTTP/1.1 + HTTP/2 (
auto_protocol): :func:run_unified_reactor_loop_shared. Per-connection preface peek selects the protocol. - HTTP/1.1 only (default):
:func:
run_reactor_loop_shared.
The frontend is :class:Copyable so the scheduler can clone
it once per worker before pthread spawn; expensive shared
state inside the user handler should be wrapped behind an
:class:Pointer so per-worker copies stay cheap.
Implements Copyable, Frontend, Movable
- Fields
handler: Hconfig: ServerConfigh2_config: Http2Configauto_protocol: Booltls_ctx_addr: Int: Address of the server's sharedSSL_CTX, or 0 for cleartext.ws_hooks: Optional[WsH2Hooks]: The server's WebSocket-over-h2 sidecar; each worker serves a copy of it (:meth:WsH2Hooks.clone).
__init__
def __init__(out self, var handler: H, var config: ServerConfig, var h2_config: Http2Config = Http2Config(), auto_protocol: Bool = False, tls_ctx_addr: Int = Int(0), ws_hooks: Optional[WsH2Hooks] = None) Build a frontend with the given handler + config combo.
- Args
handler: User request handler; cloned per worker.config: Server configuration; cloned per worker.h2_config: HTTP/2 SETTINGS used by the unified path. Ignored whenauto_protocolisFalse.auto_protocol: WhenTrue, every accepted connection auto-dispatches to the right per-conn state machine via the RFC 9113 §3.4 preface peek. WhenFalse(default), the worker speaks HTTP/1.1 exclusively.tls_ctx_addr: Address of the shared serverSSL_CTX; 0 (default) serves cleartext. When set, each accepted connection starts as a TLS handshake and its protocol is chosen by ALPN.ws_hooks: Optional WS-over-h2 sidecar handler (RFC 8441).Nonedisables the WS carrier path.
requires_per_worker_listener
def requires_per_worker_listener(self) -> Bool The io_uring buffer-ring path needs per-worker listeners.
See the trait docstring for the full rationale: the
kernel-side accept fan-out happens at multishot accept
arming time, and a shared listener with EPOLLEXCLUSIVE
would funnel every accept event through one entry. For
every other backend the scheduler is free to pick its
listener strategy from the FLARE_REUSEPORT_WORKERS
env knob (which still applies to the epoll handler /
unified paths).
run_worker
def run_worker(mut self, listener_fd: Int, mut stopping: Bool, stats_addr: Int, extra_fds: List[Int] = List()) Pick the reactor entry point and run it until stopping flips.