# flare.grpc.streaming

> A module of flare_mlake's API.

The gRPC streaming calls over a long-lived HTTP/2 stream.

The unary :class:`flare.grpc.GrpcClient.call` path buffers the whole
response and pops it in one shot. Streaming RPCs instead keep one HTTP/2
stream open and pump length-prefix-message (LPM) frames incrementally:

- **server-streaming**: one request message, then N reply messages
  surfaced one at a time via :meth:`GrpcServerStream.recv` as the
  server's DATA frames arrive (bounded memory -- only one message and
  the partial-frame reassembly buffer are held, never the whole
  response).
- **client-streaming / bidi**: the request stream stays OPEN so the
  caller pumps request messages with :meth:`GrpcBidiStream.send` and
  half-closes with :meth:`GrpcBidiStream.close_send`, then drains reply
  messages with :meth:`GrpcBidiStream.recv`.

Both ride the existing :class:`flare.http2.client.Http2ClientConnection`
driver -- the unary fast path in ``http2/client.mojo`` is untouched;
streaming only uses the additive incremental accessors
(``send_request_open`` / ``drain_body`` / ``stream_ended`` /
``response_headers``).

The transport is held behind :class:`_H2Transport` (a TCP or TLS stream
in a heap cell) so a single concrete stream type serves both h2c and h2
without leaking a transport type parameter through the public API.

## Structs

### `GrpcServerStream`

```mojo
struct GrpcServerStream
```

A live server-streaming RPC: pull reply messages one at a time.

Returned by :meth:`flare.grpc.GrpcClient.call_server_streaming`.
Call :meth:`recv` until it returns ``None`` (end of stream), then
:meth:`status` for the final ``grpc-status``.

Implements: `Movable`

#### `__init__`

```mojo
def __init__(out self, var t: _H2Transport, var conn: Http2ClientConnection, sid: Int)
```

#### `recv`

```mojo
def recv(mut self) -> Optional[List[UInt8]]
```

Return the next reply message payload, or ``None`` once the server has ended the stream and no full frame remains.

Raises: NetworkError: if the peer resets the stream or closes the
connection mid-message.

#### `status`

```mojo
def status(mut self) -> GrpcStatus
```

Return the final RPC status (``grpc-status`` / ``grpc-message`` trailer). Call after :meth:`recv` has returned ``None``. Discards the stream's per-connection state.

#### `close`

```mojo
def close(mut self)
```

Release the underlying connection (closes the socket).

### `GrpcBidiStream`

```mojo
struct GrpcBidiStream
```

A live client-streaming or bidirectional RPC.

Returned by :meth:`flare.grpc.GrpcClient.call_client_streaming` and
:meth:`flare.grpc.GrpcClient.call_bidi`. Pump request messages with
:meth:`send`, half-close the request side with :meth:`close_send`,
and drain reply messages with :meth:`recv` (then :meth:`status`).

Implements: `Movable`

#### `__init__`

```mojo
def __init__(out self, var t: _H2Transport, var conn: Http2ClientConnection, sid: Int)
```

#### `send`

```mojo
def send(mut self, message: Span[UInt8])
```

Send one request message (LPM-framed) on the open stream.

#### `close_send`

```mojo
def close_send(mut self)
```

Half-close the request side (empty DATA + END_STREAM). After this the caller may only :meth:`recv`.

#### `recv`

```mojo
def recv(mut self) -> Optional[List[UInt8]]
```

Return the next reply message, or ``None`` at end of stream.

Servers typically deliver replies only after the request side is
half-closed; for a true bidi server, replies may interleave with
:meth:`send` calls.

#### `status`

```mojo
def status(mut self) -> GrpcStatus
```

Return the final RPC status. Call after :meth:`recv` returns ``None``.

#### `close`

```mojo
def close(mut self)
```
