08 / ROUTING
clientinterceptors
Tracing, the duration log, the Prometheus families, the breaker and the deadline — the five layers a call passes on its way out.
WHERE IT SITS
INTERFACE
fn client_tracing( tracer : @trace.Tracer, now~ : () -> Int64 = @telemetry.trace_clock()) -> InterceptorfnThe tracing interceptor: open a client span for the call, run it as a child of whatever context the caller carried, and record the resulting status code on the span.
fn status_code(status : @moonrpc.Status) -> Int32fnThe numeric grpc-status of a status, the value that goes on the wire.
fn status_name(status : @moonrpc.Status) -> StringfnThe grpc-status name of a status, for a log line or a span attribute.
fn client_duration( clock : @clock.Clock, logger? : @logx.Logger, slow_ms~ : Int64 = 500L, mute~ : Array[String] = []) -> InterceptorfnThe duration interceptor: a failed call is logged at error with how long it took, and a successful one slower than slow_ms is logged as a slow call. A method listed in mute is logged without its request body, the way a login or a payment call is.
fn client_prometheus( metrics : RpcMetrics, clock : @clock.Clock) -> InterceptorfnThe Prometheus interceptor: time the call and count it under its method and status code.
fn acceptable(status : @moonrpc.Status) -> BoolfnWhether a failure says something about the peer. A cancelled or expired call says nothing about the backend, so it does not push the breaker towards open — the same split the reference implementation draws.
fn client_breaker(breaker : @breaker.Breaker) -> InterceptorfnThe breaker interceptor: a call the throttle sheds never reaches the transport, and answers Unavailable; a failure the peer caused is counted against it.
fn client_timeout(budget_ms : Int64, clock : @clock.Clock) -> InterceptorfnThe timeout interceptor: a call that ran past budget_ms is reported as DeadlineExceeded. The deadline is checked when the call returns rather than enforced against a timer: this transport runs the peer in the caller's own task, so there is no frame to abandon. A socket-backed client hands the budget to the transport, which does preempt; the decision this records is the same either way.
fn client_interceptors( conf : @conf.RpcClientMiddlewaresConf, deps : ClientDeps) -> Array[Interceptor]fnThe client chain conf asks for, outermost first.
struct ClientDepsstructEverything the client chain needs that is not a flag: the seam values a framework injects rather than looks up.
fn ClientDeps::new( clock~ : @clock.Clock = @clock.Clock::system(), tracer? : @trace.Tracer, breaker? : @breaker.Breaker, metrics? : RpcMetrics, now? : () -> Int64, timeout_ms~ : Int64 = 2000L, slow_ms~ : Int64 = 500L, mute~ : Array[String] = []) -> ClientDeps raise @metric.RefusedfnThe dependencies for a client config, with every seam at its default: a system clock, a discarding tracer, a fresh breaker and a fresh metric registry.