06 / ROUTING
p2c
Choose two instances at random and take the less loaded: sqrt(lag + 1) * (inflight + 1), with the lag and success counts moving averages that decay over ten seconds and a one-second window after which an unpicked instance is forced.
WHERE IT SITS
INTERFACE
struct P2cConfstructThe constants the picker runs on. The defaults are the reference implementation's: a ten-second decay, a one-second forced pick, a thousand starting successes, and three attempts at finding a healthy pair.
let p2c_default : P2cConf =letThe defaults.
let p2c_penalty : Int64 = 0x7FFFFFFFLletThe load a node reports when its computed one is zero: the largest 32-bit value, so it loses every comparison. Named rather than written where it is used because it is a decision, not an arithmetic detail.
struct P2cNodestructOne instance's numbers.
struct P2cstructThe picker: one P2cNode per instance, keyed by Endpoint::id.
fn P2c::new( clock~ : @clock.Clock = @clock.Clock::system(), conf~ : P2cConf = p2c_default, random? : (Int32) -> Int32) -> P2cfnA picker on clock. random answers an index in [0, n) and defaults to a counter-mixed generator, so a replay with a fixed clock and a fixed generator makes exactly the decisions the reference implementation makes.
fn sqrt(x : Double) -> DoublefnThe square root of a non-negative number, by Newton's iteration. The standard library ships exp and the trigonometric functions but no square root for Double, and rounding a load to an integer to avoid one would change which of two instances is chosen.
fn P2c::pick( self : P2c, endpoints : Array[@moonsd.Endpoint]) -> @moonsd.Endpoint?fnPick an instance, or None when there is nothing to pick. The chosen node's in-flight count goes up, and done is what brings it back down.
fn P2c::done( self : P2c, endpoint : @moonsd.Endpoint, started_ms : Int64, ok : Bool) -> UnitfnRecord a finished call on endpoint: its in-flight count comes back down, and its lag and success count move towards this call by the weight the time since the previous update earns.
fn P2c::stats( self : P2c, endpoint : @moonsd.Endpoint) -> (Int64, Int64, Int64)fnThe node's numbers, for a test or a status endpoint.