04 / ROUTING
balance
Balancers over moonpool's RoundRobin and Weighted, and a LoadBalancedChannel that resolves a service through the Resolve interface, picks an instance, and dials it over the h2c transport. Registries come from moonsd and the clients that implement it; a View of moonsd's is what a program resolves through.
WHERE IT SITS
INTERFACE
type Resolve = (String) -> Array[@moonsd.Endpoint]typeThe instances of a service. It runs on every call, so it must answer without waiting: a program passes @moonsd.View::endpoints here and runs View::follow in a task of its own.
enum BalancerenumHow a load-balanced channel chooses: in turn, in proportion to Endpoint::weight, or always the first (gRPC's pick_first). Weighted keeps its credit by Endpoint::id.
fn Balancer::round_robin() -> BalancerfnInstances in turn, from the first.
fn Balancer::weighted() -> BalancerfnInstances by weight, with no credit yet.
fn Balancer::p2c( clock~ : @clock.Clock = @clock.Clock::system(), conf~ : P2cConf = p2c_default) -> BalancerfnPower-of-two-choices over measured load.
fn Balancer::pick( self : Balancer, endpoints : Array[@moonsd.Endpoint]) -> @moonsd.Endpoint?fnOne of endpoints, or None if there is nothing to choose.
fn Balancer::report( self : Balancer, endpoint : @moonsd.Endpoint, started_ms : Int64, ok : Bool) -> UnitfnReport how a call to endpoint ended, so a load-aware balancer can move its numbers. Balancers that choose without feedback ignore it.
struct RpcClusterstructThe in-process dial table: an endpoint address maps to the RpcServer listening there. It stands in for DNS resolution plus a socket dial in the in-process h2c transport — a real deployment opens a connection to the address instead of looking the server up here, but the resolve→balance→call path above it is the same.
fn RpcCluster::new() -> RpcClusterfnAn empty cluster.
fn RpcCluster::add( self : RpcCluster, endpoint : @moonsd.Endpoint, server : @zrpc.RpcServer) -> UnitfnBind the server reachable at endpoint's address.
fn RpcCluster::dial( self : RpcCluster, endpoint : @moonsd.Endpoint) -> @zrpc.RpcChannel?fnOpen a channel to the server bound at endpoint, or None if nothing is reachable there (a stale registry entry pointing at a gone instance).
struct LoadBalancedChannelstructA load-balanced zRPC client: it resolves a service through Resolve, picks a live instance with the Balancer, dials it on the RpcCluster, and makes the call. The whole resolve→balance→dial→call path runs per call, so instances registering or deregistering between calls take effect on the next one.
fn LoadBalancedChannel::new( resolve : Resolve, cluster : RpcCluster, service : String, balancer~ : Balancer = Balancer::round_robin(), clock~ : @clock.Clock = @clock.Clock::system()) -> LoadBalancedChannelfnBuild a load-balanced channel for service over a Resolve interface, dialing through cluster with balancer (round-robin by default).
fn LoadBalancedChannel::balancer(self : LoadBalancedChannel) -> BalancerfnThe balancer this channel chooses with, so a caller can read a load-aware picker's numbers.
fn LoadBalancedChannel::call( self : LoadBalancedChannel, path : String, request : Bytes) -> Result[Bytes, @moonrpc.Status] raisefnMake a unary call to path, resolving and balancing to a live instance first.
fn LoadBalancedChannel::call_server_streaming( self : LoadBalancedChannel, path : String, request : Bytes) -> Result[Array[Bytes], @moonrpc.Status] raisefnMake a server-streaming call to path, resolving and balancing to a live instance first.
fn LoadBalancedChannel::call_bidi_streaming( self : LoadBalancedChannel, path : String, requests : Array[Bytes]) -> Result[Array[Bytes], @moonrpc.Status] raisefnMake a bidirectional-streaming call to path, resolving and balancing to a live instance first, then driving the whole requests exchange to completion.