GrpcCallContext
struct GrpcCallContext
View of the per-call HTTP/2 request state visible to the application handler.
The path field is the gRPC method name (/svc/method); the
deadline is the absolute microsecond timestamp at which the
server should abandon the call (0 means "no deadline
specified"). Initial metadata is the application-visible
subset of the request HEADERS (grpc- reserved keys are
stripped before the handler sees them).
Implements Copyable, Movable
- Fields
path: Stringdeadline_us: UInt64initial_metadata: GrpcMetadataaccept_encoding: String
GrpcUnaryReply
struct GrpcUnaryReply
Typed return value for a unary gRPC handler.
Replaces the prior Tuple[List[UInt8], GrpcStatus, GrpcMetadata]
so a handler's call site reads as return GrpcUnaryReply.ok(body)
or return GrpcUnaryReply.err(GrpcStatus.err(...)) instead of a
positional 3-tuple. The :func:run_unary_call driver always emits
an empty response body for non-OK replies; body is ignored in
that case (the spec carries the status on the trailers, not the
payload).
The two factory methods (:func:ok and :func:err) handle the
metadata-default ergonomics so a handler that does not attach
trailing metadata can omit the argument.
Implements Copyable, Movable
- Fields
body: List[UInt8]status: GrpcStatustrailing_metadata: GrpcMetadata
ok
def ok(var body: List[UInt8], var trailing_metadata: GrpcMetadata = GrpcMetadata()) -> Self
Build an OK reply carrying body and the (optional) trailing metadata. GrpcStatus.ok() is filled in for the caller.
err
def err(var status: GrpcStatus, var trailing_metadata: GrpcMetadata = GrpcMetadata()) -> Self
Build a non-OK reply carrying status plus optional trailing metadata. The body is always empty; the trailers carry the status code + message.
GrpcService
struct GrpcService[H: GrpcUnary & Copyable & Deinitable]
Adapt a :class:GrpcUnary handler into a plain :trait:Handler so it serves over the unified :class:flare.http.HttpServer H2 reactor path -- no bespoke per-RPC glue.
Mount it like any other handler::
var svc = GrpcService(EchoHandler())
var server = HttpServer.bind(addr)
server.serve(svc) # over h2c / h2
One H2 stream maps to one unary call: the reactor hands this
adapter the assembled :class:Request (HEADERS + DATA), the adapter
runs :func:run_unary_call, and returns a :class:Response whose
trailers carry grpc-status. The inner handler is copied per call
(H: Copyable) so the immutable serve borrow holds while
serve_unary mutates its own copy -- unary handlers are config-
only in practice, so the copy is cheap.
Deadlines: when the client sends grpc-timeout the adapter
enforces it as a wall-clock ceiling on the handler invocation and
returns DEADLINE_EXCEEDED if the handler overruns.
Deadline enforcement is a post-hoc elapsed check, not a
cooperative mid-call cancel (the handler runs to completion, then we
compare elapsed vs budget), so a runaway handler still burns
its full time before the status flips. Cancelling it promptly would
need a :class:flare.http.Cancel threaded into a cancel-aware
GrpcUnary variant and flipped from a deadline timer.
Implements Copyable, Handler, Movable
- Fields
handler: H
comptime BodyType = InlineBody
The Body impl this handler authors its response with.
serve
def serve(self, req: Request) -> Response