Skip to main content

Module handler

Module handler 

Source
Expand description

Handler is the served-HTTP face of the SendPipe root form: a Request<Bytes> -> Response<Bytes> pipe with Err pinned to ProximaError. Every upstream, every middleware, every composition primitive that dispatches HTTP traffic implements it. Listeners dispatch into a PipeHandle; pipelines record from one; the daemon hot-swaps them.

§Handler is the served boundary

       request                                response
          │                                      ▲
          ▼                                      │
       ┌──────────────────────────────────────────┐
       │                Handler                   │
       │  async fn call(Request) -> Result<...>   │
       └──────────────────────────────────────────┘

Handler is a blanket impl over SendPipe<In = Request<Bytes>, Out = Response<Bytes>, Err = ProximaError> — nothing to implement, any qualifying SendPipe already satisfies it. PipeHandle is the runtime-dispatch alias for the erased form so heterogeneous handlers can sit side by side. ThreadLocalHandler / ThreadLocalPipeHandle are the !Send sibling for Rc / RefCell per-core state.

§Core primitives

These are also Handlers — they wrap any inner handler and don’t care what it does. Diff runs two handlers in parallel and reports divergence; Isolate catches panics and enforces a time budget; SwappablePipe hot-swaps the inner handle at runtime without tearing in-flight calls; the daemon control plane’s apply verb rides on it.

§Recording wraps any Pipe

Recording is not a separate tracing subsystem — it composes from the same primitives. Tee-shaped wrapping (record a copy of the request/response while passing through) lives downstream in proxima-recording, built over this crate’s Handler boundary the same way every other composition primitive is.

§Serving a Handler

A Handler doesn’t serve traffic by itself. What this module owns is the step before that: a qualifying SendPipe already IS a Handler (the blanket below), and into_handle erases it into the PipeHandle a listener dispatches to. Wiring that handle to a socket is proxima_listen::registry::ServeBuilder’s job, one layer up — not linkable from here, and deliberately not shown here as an uncompiled sketch.

use bytes::Bytes;
use core::future::Future;
use proxima_core::ProximaError;
use proxima_primitives::pipe::request::{Request, Response};
use proxima_primitives::pipe::{Handler, PipeHandle, SendPipe, into_handle};

struct Health;

impl SendPipe for Health {
    type In = Request<Bytes>;
    type Out = Response<Bytes>;
    type Err = ProximaError;

    fn call(
        &self,
        _request: Request<Bytes>,
    ) -> impl Future<Output = Result<Response<Bytes>, ProximaError>> + Send {
        async { Ok(Response::typed(200, Bytes::from_static(b"ok"))) }
    }
}

fn assert_handler<H: Handler>(_: &H) {}
assert_handler(&Health);

let handle: PipeHandle = into_handle(Health);

Traits§

Handler
The served-HTTP face of SendPipe: Request<Bytes> -> Response<Bytes>, Err pinned to ProximaError. Blanket-implemented for every qualifying SendPipe — nothing to implement directly.
ThreadLocalHandler
Per-thread sibling of Handler for runtimes that pin work to a single core (DPDK, per-core executors) and may hold Rc / RefCell state. Blanket-implemented over the no-Send root Pipe.

Functions§

into_handle
Erase a Handler into a shareable PipeHandle.
into_thread_local_handle
Erase a ThreadLocalHandler into a shareable ThreadLocalPipeHandle.

Type Aliases§

PipeHandle
Erased, shareable served handler — the runtime-dispatch alias Arc<dyn SendDynPipe<Request<Bytes>, Response<Bytes>>> so heterogeneous handlers sit side by side in routing tables and swap cells.
ThreadLocalPipeHandle
Erased, shareable per-thread handler — the Rc-backed sibling of PipeHandle.