02 / RESILIENCE
shedder
The adaptive shedder over moonward's, wired from RestConf.CpuThreshold: while the CPU is above the threshold, or was within the last second, it sheds once more requests are in flight than recent throughput and latency can carry.
WHERE IT SITS
INTERFACE
struct ShedderstructLoad shedding under pressure. A request is refused only when the server is hot, its CPU at or over threshold per-mille or recently so, and full, with more requests in flight than it has shown it can finish. The algorithm is moonward's Shedder; this binds it to a Clock and to usage, the CPU meter. Without a meter usage reads zero and nothing is shed, since no MoonBit backend can read one alone.
fn Shedder::new( clock : @clock.Clock, threshold~ : Int64 = 900L, usage? : () -> Int64) -> Shedderfn
fn Shedder::allow(self : Shedder) -> Ticket?fnAsk to admit one request. Some ticket means go ahead, and the caller settles it when the request finishes; None means shed it.
fn Shedder::usage(self : Shedder) -> Int64fnThe CPU usage the shedder is reading, per mille.
struct TicketstructAn admitted request.
fn Ticket::pass(self : Ticket) -> UnitfnThe request succeeded; its duration counts towards the server's capacity.
fn Ticket::fail(self : Ticket) -> Unitfn
fn shedding( s : @shedder.Shedder, refusal~ : Refusal = unavailable) -> MiddlewarefnShedding middleware: answer 503 Service Unavailable without running the app while the shedder is refusing, and pass everything else through. Non-HTTP scopes are never shed. An admitted request whose app answers 503 is settled as failed, any other as passed, which is the one status tells its shedder apart.