Metadata uses Vec[Header]. Application -bin values are raw, binary-safe Strings; wire conversion performs Base64 and preserves duplicate order.
@ grpc_metadata_new → ( Vec Header )@ grpc_metadata_free sink ( Vec Header ) metadata → v@ grpc_header_count ( Vec Header ) headers s name → i@ grpc_header_value ( Vec Header ) headers s name → sBorrowed until headers are freed. Use count to distinguish absent/empty.
@ grpc_header_clone Header header → Header@ grpc_metadata_clone ( Vec Header ) headers → ( Vec Header )@ grpc_metadata_key String key → b@ grpc_metadata_reserved String key → b@ grpc_metadata_ascii String value → b@ grpc_metadata_add ( Vec Header ) metadata s key s value → !v GrpcError@ grpc_metadata_add_binary ( Vec Header ) metadata s key ( Vec u ) value → !v GrpcError@ grpc_headers_check_size ( Vec Header ) headers i limit → !v GrpcError@ grpc_request_headers_check_size ( Vec Header ) headers s scheme s authority s path i limit → !v GrpcErrorThe HTTP/2 client adds these four pseudoheaders when opening a POST stream. Include their decoded sizes in the same budget as application metadata.
@ grpc_metadata_encode ( Vec Header ) metadata i limit → !( Vec Header ) GrpcError@ grpc_metadata_decode ( Vec Header ) headers i limit → !( Vec Header ) GrpcError@ grpc_message_encode String message → String@ grpc_message_decode String message → StringMalformed percent escapes are preserved as required by the wire protocol.
: GrpcStatus { i code String message ( Vec u ) details }@ grpc_status i code s message → GrpcStatus@ grpc_status_free sink GrpcStatus status → v@ grpc_status_parse ( Vec Header ) headers → !GrpcStatus GrpcErrorheaders must be the final trailer block, or END_STREAM initial headers for a trailers-only response. The transport decides which block is final.
@ grpc_status_headers GrpcStatus status ( Vec Header ) metadata i limit → !( Vec Header ) GrpcErrorPublic facade. Import client.nu or server.nu separately for a smaller API.
Incremental gRPC server. A GrpcServer owns protocol state, never its TcpConn. Unary, client streaming, server streaming, and bidirectional calls share this event API. send accepts one complete message into a bounded queue; flush writes only available HTTP/2 credit and next services the peer.
: GrpcServerLimits: GrpcServerLimits {
i max_message
i max_buffer
i max_metadata
i max_calls
i max_connection_buffer
i idle_timeout_ns
}
@ grpc_server_limits → GrpcServerLimits: GrpcServerCall: GrpcServerCall {
i stream_id
String method
GrpcDecoder decoder
i deadline_ns
b input_ended
b end_notified
b headers_sent
b output_finished
b cancelled
b accepts_gzip
i output_encoding
( Vec u ) outgoing
i outgoing_pos
( Vec Header ) trailers
b finish_requested
( Vec Header ) request_trailers
}
: GrpcServer: GrpcServer {
H2Connection transport
GrpcServerLimits limits
( Vec GrpcServerCall ) calls
i cursor
b closed
}
: GrpcServerEvent: GrpcServerEvent {
i kind
i stream_id
String method
( Vec Header ) metadata
( Vec u ) message
i code
}
@ grpc_server_event_control → i@ grpc_server_event_open → i@ grpc_server_event_message → i@ grpc_server_event_half_close → i@ grpc_server_event_cancelled → i@ grpc_server_event_closed → i@ grpc_server_event_free sink GrpcServerEvent event → v@ grpc_server_free sink GrpcServer server → v@ grpc_server_deadline GrpcServer server i sid → !i GrpcError@ grpc_server_is_cancelled GrpcServer server i sid → b@ grpc_server_new TcpConn conn GrpcServerLimits limits → !GrpcServer GrpcError@ grpc_server_send_metadata inout GrpcServer server i sid ( Vec Header ) metadata i encoding → !v GrpcError@ grpc_server_flush inout GrpcServer server → !v GrpcErrorFlushes queued frames without consuming any peer frame. A stalled stream does not prevent another stream from sending or receiving messages.
@ grpc_server_send inout GrpcServer server i sid ( Vec u ) message → !v GrpcErrorSuccess means the message was accepted. The caller keeps its input; the server owns the encoded frame until all bytes have reached the peer.
@ grpc_server_finish inout GrpcServer server i sid GrpcStatus status ( Vec Header ) metadata → !v GrpcError@ grpc_server_next inout GrpcServer server → !GrpcServerEvent GrpcError@ grpc_server_next_until inout GrpcServer server i poll_deadline_ns → !GrpcServerEvent GrpcErrorApplication timers can wake an idle connection without cancelling its RPCs. An expired poll deadline returns control; RPC deadlines still produce cancelled events and terminal status. Zero uses the ordinary idle bound.
gRPC message framing and protocol values. Inputs are borrowed; returned buffers and GrpcError messages are owned. No protobuf schema is assumed.
: i GRPC_OK 0: i GRPC_CANCELLED 1: i GRPC_UNKNOWN 2: i GRPC_INVALID_ARGUMENT 3: i GRPC_DEADLINE_EXCEEDED 4: i GRPC_NOT_FOUND 5: i GRPC_ALREADY_EXISTS 6: i GRPC_PERMISSION_DENIED 7: i GRPC_RESOURCE_EXHAUSTED 8: i GRPC_FAILED_PRECONDITION 9: i GRPC_ABORTED 10: i GRPC_OUT_OF_RANGE 11: i GRPC_UNIMPLEMENTED 12: i GRPC_INTERNAL 13: i GRPC_UNAVAILABLE 14: i GRPC_DATA_LOSS 15: i GRPC_UNAUTHENTICATED 16: i GRPC_IDENTITY 0: i GRPC_GZIP 1: i GRPC_DEFAULT_MAX_MESSAGE 4194304: i GRPC_DEFAULT_MAX_METADATA 8192: GrpcError { i code String message }@ grpc_error i code s message → GrpcError@ grpc_error_free sink GrpcError e → v@ grpc_code_name i code → s@ grpc_http_status i status → i@ grpc_reset_status i code → i@ grpc_encoding_name i encoding → s@ grpc_encoding s name → !i GrpcError@ grpc_content_type String value → b@ grpc_method_path s path → b@ grpc_timeout_ns String value → !i GrpcErrorTimeout parsing is strict, uses every defined unit, and saturates instead of overflowing for the protocol's largest (99,999,999 hour) duration.
@ grpc_timeout_value i duration_ns → StringRound up so the wire timeout never expires before the caller's duration.
@ grpc_deadline_after i now_ns i duration_ns → i@ grpc_frame ( Vec u ) message i encoding i max_message → !( Vec u ) GrpcErrorBoth compressed and uncompressed sizes are bounded. Each message gets its own compression context, including the empty protobuf message.
: GrpcMessage { b present ( Vec u ) data }: GrpcDecoder { ( Vec u ) pending i pos i max_message i max_buffer i encoding }@ grpc_message_free sink GrpcMessage message → v@ grpc_decoder i max_message i max_buffer i encoding → !GrpcDecoder GrpcError@ grpc_decoder_free sink GrpcDecoder d → v@ grpc_decoder_feed inout GrpcDecoder d ( Vec u ) bytes → !v GrpcErrorAtomic on error. Call next repeatedly after each feed until present=false.
@ grpc_decoder_next inout GrpcDecoder d → !GrpcMessage GrpcError@ grpc_decoder_finish GrpcDecoder d → !v GrpcErrorCalled after draining messages when the HTTP/2 receive side ends.
HTTP/2-backed gRPC calls. A client and all its calls have one owner/driver. Calls borrow their client's transport; release calls before closing client. Sending borrows protobuf bytes. Receiving transfers an owned GrpcMessage.
: GrpcClient { H2Client transport String scheme String authority b owns_transport }: GrpcCallOptions { i timeout_ns i max_send_message i max_recv_message i max_metadata i encoding }: GrpcCall: GrpcCall {
H2Client transport
i stream_id
GrpcDecoder decoder
i max_send_message
i max_metadata
i encoding
b response_checked
b status_checked
GrpcStatus status
( Vec Header ) headers
( Vec Header ) trailers
}
: GrpcUnaryResponse { ( Vec u ) data ( Vec Header ) headers ( Vec Header ) trailers GrpcStatus status }@ grpc_call_options → GrpcCallOptions@ grpc_client_from_h2 H2Client transport s scheme s authority → GrpcClient@ grpc_client_connect_h2c s host i port → !GrpcClient GrpcError@ grpc_client_connect_tls s host i port b verify → !GrpcClient GrpcError@ grpc_client_close sink GrpcClient client → v@ grpc_call_open GrpcClient client s path ( Vec Header ) metadata GrpcCallOptions opts → !GrpcCall GrpcError@ grpc_call_cancel inout GrpcCall call → !v GrpcError@ grpc_call_free sink GrpcCall call → vAlways cancels unfinished calls so application early-return releases the peer's stream resources as well as the local decoder and metadata.
@ grpc_call_send inout GrpcCall call ( Vec u ) message → !v GrpcErrorQueue one framed message. RESOURCE_EXHAUSTED/H2CWouldBlock leaves the borrowed input untouched: receive/pump existing messages before retrying.
@ grpc_call_half_close inout GrpcCall call → !v GrpcError@ grpc_call_pump inout GrpcCall call → !v GrpcError@ grpc_call_receive inout GrpcCall call → !GrpcMessage GrpcErrorReceive one message, or present=false after successful final status. The same primitive supports unary and all three streaming RPC cardinalities.
@ grpc_unary_response_free sink GrpcUnaryResponse response → v@ grpc_unary GrpcClient client s path ( Vec u ) request ( Vec Header ) metadata GrpcCallOptions opts → !GrpcUnaryResponse GrpcError