Expand description
Queue consumer presence — issue #742.
Tracks consumer liveness as an explicit heartbeat contract that is orthogonal to pending-delivery state. Red UI needs to render “is anyone reading queue X / group Y right now?” without inferring it from PEL entries: a worker can be alive on a quiet queue with zero pending deliveries, and a worker with stuck PEL entries may itself be dead. Presence is the answer to that question.
Contract surface (process-local registry):
heartbeat(queue, group, consumer, lease_count)— record or refresh the last-seen timestamp for a(queue, group, consumer)triple. Called on everyQUEUE READ(whether or not a message was returned) so an idle poller still counts as alive, and may be called explicitly by aQUEUE HEARTBEATcommand in a follow- up slice.snapshot(now_ns, ttl_ms)— list every tracked consumer with the derivedlast_seen_age_ms,lease_count, and lifecycle flags (active/stale/expired). Stale means the consumer missed at least one heartbeat budget but is still tracked; expired means it crossed the prune horizon and is queued for removal on the next sweep.count_active_by_group(now_ns, ttl_ms)— per-(queue, group)active consumer count, the field the operator-facing metadata surfaces consume.prune_expired(now_ns, ttl_ms)— drop entries whose age exceeds2 * ttl_ms(the expiry horizon). Safe to call on every snapshot path or on a background timer.
Aliveness model:
age_ms <= ttl_ms→ activettl_ms < age_ms <= 2 * ttl_ms→ stale (one missed beat)age_ms > 2 * ttl_ms→ expired (prune-eligible)
Durability follow-up: this slice is the typed contract + the
metadata snapshot every consumer of presence (Red UI, red.*
virtual tables, drivers) talks to. Mirroring writes into
red_queue_meta rows so presence survives restart is the
immediately-next slice; the public surface here does not change
when that lands.
Structs§
- Consumer
Presence - One row of presence state, returned by
snapshot. - Consumer
Presence Registry - Process-local registry of consumer presence. Cheap mutex + small hashmap is the right shape: writes are O(1), reads are a single snapshot copy, and the cardinality is bounded by the operator’s worker fleet (typically dozens, not thousands).
Enums§
- Presence
State - Lifecycle bucket derived from
last_seen_age_msvs the configuredttl_ms. Snapshot consumers (Red UI, virtual tables) read this flag and never re-derive the rule.
Constants§
- DEFAULT_
PRESENCE_ TTL_ MS - Default heartbeat budget — a consumer is considered active for this long after its last beat. Operators can override per server via the runtime config; the registry itself is agnostic and takes the budget as an argument on every read path.