livery_service (livery v0.1.0)
View SourceService runtime.
Brings up H3 on UDP, H2 on TLS, and H1 on TCP under one supervisor, sharing one router/middleware/handler. Optionally advertises Alt-Svc on H1 and H2 responses so clients race up to H3.
Configuration map:
livery:start_service(#{
host => <<"example.com">>,
http3 => #{port => 443, cert => Cert, key => Key},
https => #{port => 443, cert => Cert, key => Key},
http => #{port => 80},
handler => fun handler/1,
middleware => Stack,
alt_svc => advertise
}).Supply exactly one of handler (a single catch-all) or router
(a compiled livery_router the service dispatches through, via
livery:router_handler/1).
Returns {ok, ServicePid}. The service pid owns the listeners and
shuts them down when stopped via livery:stop_service/1. A crash
takes them all down together. For a polite shutdown that lets
in-flight requests finish, use livery:drain/1,2.
Summary
Functions
Start a service from a config map.
Stop a running service.
Stop the service's listeners (no new connections) while leaving
the gen_server and any in-flight requests running. Used by
livery_drain to begin a graceful shutdown.
Return the ports the service is bound to, by protocol. Keys are present only for protocols that were configured.
Types
-type listener_opts() :: #{port => inet:port_number(), cert => binary() | string(), key => binary() | string() | term(), cacerts => [binary()], acceptors => pos_integer(), settings => map(), quic_opts => map()}.
-type service_opts() :: #{host => binary(), http => listener_opts(), https => listener_opts(), http3 => listener_opts(), handler => livery_middleware:handler(), router => livery_router:router(), middleware => livery_middleware:stack(), alt_svc => advertise | none}.
Functions
-spec code_change(term(), #state{h1 :: {livery_h1:listener(), inet:port_number()} | undefined, h2 :: {livery_h2:listener(), inet:port_number()} | undefined, h3 :: {livery_h3:listener(), inet:port_number()} | undefined}, term()) -> {ok, #state{h1 :: {livery_h1:listener(), inet:port_number()} | undefined, h2 :: {livery_h2:listener(), inet:port_number()} | undefined, h3 :: {livery_h3:listener(), inet:port_number()} | undefined}}.
-spec handle_call(term(), {pid(), term()}, #state{h1 :: {livery_h1:listener(), inet:port_number()} | undefined, h2 :: {livery_h2:listener(), inet:port_number()} | undefined, h3 :: {livery_h3:listener(), inet:port_number()} | undefined}) -> {reply, term(), #state{h1 :: {livery_h1:listener(), inet:port_number()} | undefined, h2 :: {livery_h2:listener(), inet:port_number()} | undefined, h3 :: {livery_h3:listener(), inet:port_number()} | undefined}}.
-spec handle_cast(term(), #state{h1 :: {livery_h1:listener(), inet:port_number()} | undefined, h2 :: {livery_h2:listener(), inet:port_number()} | undefined, h3 :: {livery_h3:listener(), inet:port_number()} | undefined}) -> {noreply, #state{h1 :: {livery_h1:listener(), inet:port_number()} | undefined, h2 :: {livery_h2:listener(), inet:port_number()} | undefined, h3 :: {livery_h3:listener(), inet:port_number()} | undefined}}.
-spec handle_info(term(), #state{h1 :: {livery_h1:listener(), inet:port_number()} | undefined, h2 :: {livery_h2:listener(), inet:port_number()} | undefined, h3 :: {livery_h3:listener(), inet:port_number()} | undefined}) -> {noreply, #state{h1 :: {livery_h1:listener(), inet:port_number()} | undefined, h2 :: {livery_h2:listener(), inet:port_number()} | undefined, h3 :: {livery_h3:listener(), inet:port_number()} | undefined}}.
-spec init(service_opts()) -> {ok, #state{h1 :: {livery_h1:listener(), inet:port_number()} | undefined, h2 :: {livery_h2:listener(), inet:port_number()} | undefined, h3 :: {livery_h3:listener(), inet:port_number()} | undefined}} | {stop, term()}.
-spec start_link(service_opts()) -> {ok, pid()} | {error, term()}.
Start a service from a config map.
-spec stop(pid()) -> ok.
Stop a running service.
-spec stop_accepting(pid()) -> ok.
Stop the service's listeners (no new connections) while leaving
the gen_server and any in-flight requests running. Used by
livery_drain to begin a graceful shutdown.
-spec terminate(term(), #state{h1 :: {livery_h1:listener(), inet:port_number()} | undefined, h2 :: {livery_h2:listener(), inet:port_number()} | undefined, h3 :: {livery_h3:listener(), inet:port_number()} | undefined}) -> ok.
-spec which_listeners(pid()) -> #{h1 | h2 | h3 => inet:port_number()}.
Return the ports the service is bound to, by protocol. Keys are present only for protocols that were configured.