nquic_protocol_streams_lifecycle (nquic v1.0.0)

View Source

Stream terminal-state cleanup and stream-limit bookkeeping.

Pure functions over #conn_state{} that decide when a stream has reached a terminal state and reclaim it: per-side terminal predicates (is_stream_terminal/3, is_send_done/1, is_recv_done/1, is_closed_stream/2), terminal-state reclamation. The recv-side predicate treats size_known with an empty app buffer as terminal: the peer's FIN has been delivered and there is nothing left for the caller to drain, so the stream can be reclaimed without waiting for an explicit recv round-trip from the application. (maybe_cleanup_stream/2,3, cleanup_stream/2), the watermark bookkeeping that keeps closed_peer_streams bounded (record_peer_closed/2, advance_peer_wm/3, set_peer_wm/3), and MAX_STREAMS window-update emission as peer-initiated streams are consumed and reclaimed (bump_max_streams/2, maybe_send_max_streams/2, maybe_auto_extend_max_streams/2, peer_consumed_bidi_streams/1, peer_consumed_uni_streams/1).

cleanup_stream/2 purges the reclaimed stream from the send-side pending/blocked indices via nquic_protocol_streams_send; the send engine calls back here for maybe_cleanup_stream/3 and maybe_auto_extend_max_streams/2.

Summary

Functions

bump_max_streams(StreamID, State)

-spec bump_max_streams(nquic:stream_id(), nquic_protocol:state()) -> nquic_protocol:state().

is_closed_stream(StreamID, State)

-spec is_closed_stream(nquic:stream_id(), nquic_protocol:state()) -> boolean().

is_stream_terminal/3

-spec is_stream_terminal(nquic:stream_id(),
                         client | server | undefined,
                         #stream_state{stream_id :: nquic:stream_id(),
                                       type :: bidi | uni,
                                       send_state ::
                                           ready | send | data_sent | data_recvd | reset_sent |
                                           reset_recvd,
                                       send_offset :: non_neg_integer(),
                                       send_max_data :: non_neg_integer(),
                                       last_stream_data_blocked :: non_neg_integer(),
                                       pending_send_data :: [binary()],
                                       pending_send_size :: non_neg_integer(),
                                       pending_send_fin :: boolean(),
                                       recv_state ::
                                           recv | size_known | data_recvd | reset_recvd | data_read |
                                           reset_read,
                                       recv_offset :: non_neg_integer(),
                                       recv_max_offset :: non_neg_integer(),
                                       recv_window :: non_neg_integer(),
                                       recv_buffer ::
                                           gb_trees:tree(non_neg_integer(), {binary(), boolean()}),
                                       app_buffer :: iodata(),
                                       app_buffer_size :: non_neg_integer()}) ->
                            boolean().

maybe_auto_extend_max_streams/2

-spec maybe_auto_extend_max_streams(bidi | uni, nquic_protocol:state()) -> nquic_protocol:state().

maybe_cleanup_stream(StreamID, State)

-spec maybe_cleanup_stream(nquic:stream_id(), nquic_protocol:state()) -> nquic_protocol:state().

maybe_cleanup_stream(StreamID, Stream, State)

-spec maybe_cleanup_stream(nquic:stream_id(),
                           #stream_state{stream_id :: nquic:stream_id(),
                                         type :: bidi | uni,
                                         send_state ::
                                             ready | send | data_sent | data_recvd | reset_sent |
                                             reset_recvd,
                                         send_offset :: non_neg_integer(),
                                         send_max_data :: non_neg_integer(),
                                         last_stream_data_blocked :: non_neg_integer(),
                                         pending_send_data :: [binary()],
                                         pending_send_size :: non_neg_integer(),
                                         pending_send_fin :: boolean(),
                                         recv_state ::
                                             recv | size_known | data_recvd | reset_recvd | data_read |
                                             reset_read,
                                         recv_offset :: non_neg_integer(),
                                         recv_max_offset :: non_neg_integer(),
                                         recv_window :: non_neg_integer(),
                                         recv_buffer ::
                                             gb_trees:tree(non_neg_integer(), {binary(), boolean()}),
                                         app_buffer :: iodata(),
                                         app_buffer_size :: non_neg_integer()},
                           nquic_protocol:state()) ->
                              nquic_protocol:state().

peer_consumed_bidi_streams/1

-spec peer_consumed_bidi_streams(nquic_protocol:state()) -> non_neg_integer().

peer_consumed_uni_streams/1

-spec peer_consumed_uni_streams(nquic_protocol:state()) -> non_neg_integer().