quic_dist_controller (quic v1.8.2)
View SourcePer-connection distribution controller.
This module manages a single distribution connection over QUIC, handling:
- Control stream (stream 0) for handshake and tick messages - Data stream pool for distribution messages - Message framing with length prefixes - Tick handling for connection liveness - Stream prioritization
Stream Layout
Stream 0: Control (urgency 0) - Distribution handshake messages - Tick messages - Link/monitor signals
Streams 4,8,12...: Data (urgency 4-6) - Regular distribution messages - Round-robin scheduling
Summary
Functions
Register to accept incoming user streams. The controller auto-assigns ownership of each new incoming stream to the registered acceptor and delivers data directly as {quic_dist_stream, StreamRef, {data, Data, Fin}} messages. No prior {incoming, StreamId} handshake.
Hand QUIC events buffered by a previous owner to a controller.
Close a user stream.
Transfer stream ownership to another process.
Get address information for the connection.
Get the other node name.
Get low-level controller (self).
Get connection statistics.
List all user streams. Returns a list of stream info maps.
Open a user stream for application use. Returns {ok, StreamId} on success.
Open a user stream with options. Options: {priority, 16..255} - Stream priority (default: 128, lower = higher priority)
Pre-nodeup callback - sends dist_ctrlr message to kernel. Called by f_setopts_pre_nodeup. SetupPid is the calling process.
Receive data from the control stream.
Reset/cancel a user stream (notifies peer immediately). Uses default error code 0.
Reset/cancel a user stream with a specific error code.
Send data on the control stream.
Send data on a user stream. Fin=true marks the end of data on this stream.
Set the other node name.
Set the supervisor process (kernel).
Start a controller for a QUIC distribution connection.
Start a controller, optionally gating it behind an auth handshake.
Stop accepting incoming user streams.
Send a tick message.
Functions
Register to accept incoming user streams. The controller auto-assigns ownership of each new incoming stream to the registered acceptor and delivers data directly as {quic_dist_stream, StreamRef, {data, Data, Fin}} messages. No prior {incoming, StreamId} handshake.
-spec adopt_owner_events(Conn :: pid(), Controller :: pid()) -> non_neg_integer().
Hand QUIC events buffered by a previous owner to a controller.
The connecting setup process owns the connection until the controller starts, and the controller takes ownership in its init/1, so by the time this runs the caller's mailbox holds exactly what arrived before the swap and can receive nothing further.
Only events the controller understands cross over. A setup process may also have run an auth callback on a stream of its own; those bytes are not distribution traffic, and forward_pending_data/1 would feed them to the VM's dist input. Anything not matched here stays in the caller's mailbox, which is what {EXIT', _, remarked}' and the setup timer depend on.
-spec close_user_stream(Controller :: pid(), StreamId :: non_neg_integer()) -> ok | {error, term()}.
Close a user stream.
-spec controlling_process(Controller :: pid(), StreamId :: non_neg_integer(), NewOwner :: pid()) -> ok | {error, term()}.
Transfer stream ownership to another process.
-spec get_address(Controller :: pid(), Node :: node()) -> {ok, #net_address{address :: term(), host :: term(), protocol :: term(), family :: term()}}.
Get address information for the connection.
Get the other node name.
Get low-level controller (self).
-spec getstat(Controller :: pid()) -> {ok, RecvCnt :: non_neg_integer(), SendCnt :: non_neg_integer(), SendPend :: non_neg_integer()}.
Get connection statistics.
List all user streams. Returns a list of stream info maps.
-spec open_user_stream(Controller :: pid(), Owner :: pid()) -> {ok, non_neg_integer()} | {error, term()}.
Open a user stream for application use. Returns {ok, StreamId} on success.
-spec open_user_stream(Controller :: pid(), Owner :: pid(), Opts :: list()) -> {ok, non_neg_integer()} | {error, term()}.
Open a user stream with options. Options: {priority, 16..255} - Stream priority (default: 128, lower = higher priority)
-spec pre_nodeup(Controller :: pid()) -> ok.
Pre-nodeup callback - sends dist_ctrlr message to kernel. Called by f_setopts_pre_nodeup. SetupPid is the calling process.
-spec recv(Controller :: pid(), Length :: non_neg_integer(), Timeout :: timeout()) -> {ok, [byte()]} | {error, term()}.
Receive data from the control stream.
-spec reset_user_stream(Controller :: pid(), StreamId :: non_neg_integer()) -> ok | {error, term()}.
Reset/cancel a user stream (notifies peer immediately). Uses default error code 0.
-spec reset_user_stream(Controller :: pid(), StreamId :: non_neg_integer(), ErrorCode :: non_neg_integer()) -> ok | {error, term()}.
Reset/cancel a user stream with a specific error code.
Send data on the control stream.
-spec send_user_data(Controller :: pid(), StreamId :: non_neg_integer(), Data :: iodata(), Fin :: boolean()) -> ok | {error, term()}.
Send data on a user stream. Fin=true marks the end of data on this stream.
Set the other node name.
Set the supervisor process (kernel).
Start a controller for a QUIC distribution connection.
-spec start_link(Conn :: pid(), Role :: client | server, Auth :: undefined | {quic_dist:auth_callback(), timeout()}) -> {ok, pid()} | {error, term()}.
Start a controller, optionally gating it behind an auth handshake.
With an auth spec the server-role controller stays in init_state until the QUIC handshake completes, runs the callback, and only then admits the connection to dist_util.
-spec stop_accepting_streams(Controller :: pid()) -> ok.
Stop accepting incoming user streams.
-spec tick(Controller :: pid()) -> ok.
Send a tick message.