///|
/// Heartbeat bookkeeping for one connection: the send time of the beat still
/// awaiting its ACK, if any. A second beat before the ACK restarts the clock.
priv struct Heartbeat {
mut outstanding_since : Int64?
}
///|
fn Heartbeat::new() -> Heartbeat {
{ outstanding_since: None, }
}
///|
/// Whether the last beat is still unacknowledged. A beat that is due while
/// this holds means the connection is a zombie.
fn Heartbeat::awaiting_ack(self : Heartbeat) -> Bool {
self.outstanding_since is Some(_)
}
///|
fn Heartbeat::beat(self : Heartbeat, now : Int64) -> Unit {
self.outstanding_since = Some(now)
}
///|
/// Record an ACK and return the round-trip latency, or `None` when no beat
/// was outstanding (an unsolicited or duplicate ACK measures nothing).
fn Heartbeat::ack(self : Heartbeat, now : Int64) -> Int64? {
guard self.outstanding_since is Some(sent_at) else { return None }
self.outstanding_since = None
Some(now - sent_at)
}