livery_translator (livery v0.13.0)
View SourceThe per-request translator shared by the HTTP adapters.
Every wire library (h1, h2, quic_h3) runs Livery's handler fun in
a process of its own for each request, and sends that request's body,
trailers and resets to it in the library's own message format. This
module turns that process into the request's translator:
- it starts the request worker (
livery_req_proc), which runs the middleware and the handler; - it turns the library's events into the
{livery_body, Ref, _}messageslivery_bodyreads in the worker, so neither the body reader nor the handler ever sees a protocol-specific message; - it enforces the listener's
max_bodybefore the bytes reach the worker's mailbox; - it notices a disconnect (stream reset or connection gone) while the
worker is busy in user code, and tells it (
livery_disconnect).
It runs until the worker exits. An adapter builds the request,
registers the stream with its library if the library needs that, and
calls serve/2 with:
tagandkey: the first two elements of the library's{Tag, Key, Event}messages for this request (h1_streamand the stream id on H1;h2orquic_h3and the connection on H2 and H3);classify: turnsEventinto{data, Chunk, Fin},{trailers, Headers},{reset, Reason}orignore;conn: the connection process, watched for a disconnect;credit: optional, called with the number of body bytes the handler has just read (livery_body:read/2reports them), so the adapter can return that credit to its wire library's flow control. Without it the library's own window management applies;on_abandoned: what to tell the client when the worker finishes while the body is still coming (unread, or overmax_body), ornone.
An adapter that hands the stream to another process (a WebSocket or
WebTransport session) calls release/1 first, so the translator lets
the stream go instead of telling the client to stop.
You do not call it directly.
Summary
Functions
Called from the request worker by an adapter about to hand the stream
to another process (accept_ws/4, accept_wt/4): the translator stops
treating the body as unfinished, so it does not tell the client to stop
when the worker exits.
Start the worker for Req and translate until it exits. Answers 503
through the adapter when the request limit refuses it.
Split a request target into its path and its query string.
Translate for Worker until it exits. serve/2 calls it once the worker
is started; it is exported for the unit tests.
Types
-type opts() :: #{adapter := module(), stream := livery_adapter:stream(), stack := livery_middleware:stack(), handler := livery_middleware:handler(), max_body := non_neg_integer() | infinity, config := term(), raw_query := binary(), wire := wire(), atom() => term()}.
Functions
-spec release(livery_req:req()) -> ok.
Called from the request worker by an adapter about to hand the stream
to another process (accept_ws/4, accept_wt/4): the translator stops
treating the body as unfinished, so it does not tell the client to stop
when the worker exits.
-spec serve(livery_req:req(), opts()) -> ok.
Start the worker for Req and translate until it exits. Answers 503
through the adapter when the request limit refuses it.
Split a request target into its path and its query string.
-spec translate(pid(), #{body_ref := reference(), disc_ref := reference(), max_body := non_neg_integer() | infinity, wire := wire()}) -> ok.
Translate for Worker until it exits. serve/2 calls it once the worker
is started; it is exported for the unit tests.