///|
/// Shedding middleware (← go-zero's `SheddingHandler`): 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 go-zero tells its shedder apart.
pub fn shedding(
s : @shedder.Shedder,
refusal~ : Refusal = unavailable,
) -> Middleware {
inner => {
(scope, receive, send) => {
match scope {
Http(_) =>
match s.allow() {
Some(ticket) => {
let status : Ref[Int32] = { val: 200, }
let observed : @moonasgi.Send = event => {
if event is HttpResponseStart(status=code, ..) {
status.val = code
}
send(event)
}
defer (if status.val == 503 {
ticket.fail()
} else {
ticket.pass()
})
inner(scope, receive, observed)
}
None =>
for event in refusal.events() {
send(event)
}
}
_ => inner(scope, receive, send)
}
}
}
}