Skip to main content

Module presence

Module presence 

Source
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 every QUEUE READ (whether or not a message was returned) so an idle poller still counts as alive, and may be called explicitly by a QUEUE HEARTBEAT command in a follow- up slice.
  • snapshot(now_ns, ttl_ms) — list every tracked consumer with the derived last_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 exceeds 2 * ttl_ms (the expiry horizon). Safe to call on every snapshot path or on a background timer.

Aliveness model:

  • age_ms <= ttl_msactive
  • ttl_ms < age_ms <= 2 * ttl_msstale (one missed beat)
  • age_ms > 2 * ttl_msexpired (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§

ConsumerPresence
One row of presence state, returned by snapshot.
ConsumerPresenceRegistry
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§

PresenceState
Lifecycle bucket derived from last_seen_age_ms vs the configured ttl_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.