relayed

fun relayed(update: EphemeralMap<V>)

Merge state this replica did not receive from its author — an anti-entropy round, a full-state exchange, a forwarded slot, a merged map echoed back. The compliant way to feed a tracker anything received must not be given.

A pure join plus a receive-time stamp for entries that genuinely advance the local state. Nothing here can evict, so no relayed frame can drop a tombstone or displace a standing entry; and a non-advancing frame stamps nothing, so re-delivering state this replica already holds is a complete no-op however many rounds run.

What relaying still costs, and its bound: an entry that does advance the local state re-stamps the TTL even though its author may be long gone, so a relayed replica can read live for one window per distinct entry of its slot still circulating. That total is finite and monotonically exhausted — once this replica holds the highest entry the network has for a slot, no further relay of it can ever stamp again. Contrast received, where a differing frame re-arms the timer on every delivery, without bound.

Presence is a claim about the author being alive now, and only the author can make it. Route each replica's own heartbeat to received and everything else here.

Samples

val a = ReplicaId("A")
var now = 0L
val tracker = EphemeralMapTracker<String>(ttlMs = 5_000L, clock = { now })

// A heartbeat straight from its author: `received` — this is what liveness is measured on.
val heartbeat = EphemeralMap.empty<String>().put(a, "editing", clock = 1L)
tracker.received(heartbeat)
check(tracker.live()[a] == "editing")

// A goes silent and ages out.
now = 5_000L
check(a !in tracker.live())

// An anti-entropy round re-delivers A's last frame, held by some other peer. Merged with
// `relayed` it joins the state without re-stamping the TTL, so A stays correctly absent.
tracker.relayed(heartbeat)
check(a !in tracker.live())
check(tracker.snapshot().entries[a]?.clock == 1L)