///|
pub struct Health {
priv accepted : Ref[Int32]
priv filtered : Ref[Int32]
priv dropped : Ref[Int32]
priv unavailable : Ref[Int32]
}
///|
pub fn Health::new() -> Health {
{ accepted: Ref(0), filtered: Ref(0), dropped: Ref(0), unavailable: Ref(0), }
}
///|
pub fn Health::to_json(self : Health) -> Json {
{
"accepted": self.accepted.val,
"filtered": self.filtered.val,
"dropped": self.dropped.val,
"unavailable": self.unavailable.val,
}
}
///|
/// Per-observer delivery isolation, with a non-recursive health channel.
/// Host callbacks perform only bounded enqueue work. Drain is host-owned.
pub fn Observer::isolated(self : Observer, health : Health) -> Observer {
let busy = Ref(false)
{
..self,
try_record: fn(record) {
let delivery = if busy.val {
Dropped
} else {
busy.val = true
let result = (self.try_record)(record) catch { _ => Unavailable }
busy.val = false
result
}
match delivery {
Accepted => health.accepted.val += 1
Filtered => health.filtered.val += 1
Dropped => health.dropped.val += 1
Unavailable => health.unavailable.val += 1
}
delivery
},
}
}
///|
pub fn Observer::record(self : Observer, record : Observation) -> Delivery {
(self.try_record)(record) catch {
_ => Unavailable
}
}