jonnifyechomq

The owned keyspace · dive 03 · the reserve

The reserve

Some state belongs to the wire, not a queue. It needs a home no queue can occupy.

Not everything the protocol stores belongs to a queue — the version fence is one record for the whole wire. It needs a home no queue can name. That home is the reserve: {emq}:, built by EchoMQ.Keyspace.reserve/1, holding version_key/0 → {emq}:version. The reserve is first-byte-disjoint from every per-queue emq: key — so a queue named emq still cannot collide with it.

Two spaces · pick one to read its first byte

e emq:{orders}:pending per-queue · first byte 'e' { {emq}:version reserve · first byte '{'

First-byte-disjoint, by construction

The reserve exists because some state is the wire's own, shared by every queue and every speaker — and it needs a home that no queue can occupy. The mechanism is simple and total: the reserve and the per-queue space differ in their first byte.

A per-queue key starts with the literal emq: — emq:{orders}:pending begins with the byte e. A reserve key starts with {emq}: — it begins with the byte {. The two spaces can never share a prefix, so a key in one is never mistaken for a key in the other. The reserve is also its own hashtag: {emq} routes every cross-queue key to one slot, the same way a queue's {q} does, so the fence is single-slot too.

emq:{q}:<type>
per-queue space — first byte e; the hashtag is the queue.
{emq}:<suffix>
the reserve — first byte {; the hashtag is emq.

reserve/1 & version_key/0 — one base, one key in use

The reserve is a module constant; reserve/1 appends a suffix to it, and version_key/0 is the one reserved key the core uses today — the version fence.

# echo_mq — EchoMQ.Keyspace
# The reserve is the braced base {emq}: — the cross-queue space, structurally
# disjoint from a queue's emq: prefix (different first byte). reserve/1 builds
# any cross-queue key; version_key/0 is the one in use — the version fence.
@reserve "{emq}:"
@version_key @reserve <> "version"

def reserve(suffix) when is_binary(suffix), do: @reserve <> suffix

def version_key, do: @version_key

So version_key() is {emq}:version, and reserve("anything") is {emq}:anything. Every cross-queue key the core will ever need is built from the one reserved base, so there is exactly one place the wire's own state lives — and it is a place no queue can name.

The reserve in use — the version fence

The fence is the reserve's reason to exist. The connector reads {emq}:version before it runs a single command: if the record is absent it claims it (set-if-not-exists, then read it back); if it is present it must match the wire version the connector was built for; a mismatch is fatal. A speaker that does not agree on the wire is refused at boot — the fence is what keeps a stale or foreign client from writing into a keyspace it does not understand.

The point here is only where the fence lives: in the reserve, not in any queue. Because {emq}:version is first-byte-disjoint from every queue's keys, no queue's traffic can ever touch it, and no queue can be created that would shadow it. The mechanism of the check — how the version is compared, and the constant it is compared against — is the next module, Immutability & branded ids.

Can a queue collide with the reserve?

The obvious worry: what if a caller names a queue emq? Type any queue name below. The page builds its pending key the way queue_key/2 does and prints the reserve key beside it, then compares their first bytes. A per-queue key always starts e; the reserve always starts { — so even the queue named emq, whose key is emq:{emq}:pending, cannot collide with {emq}:version.

queue_key vs the reserve · do they collide?

The reserve is disjoint by its first byte, not by a rule a caller could break. A queue named emq is harmless: its keys still start e, and the reserve still starts {.

Pattern → implementation

the pattern (Redis Patterns Applied)

Reserve a disjoint key prefix for system-owned state, so application keys and infrastructure keys can never collide — a namespace partition by construction rather than by convention. Redis Patterns Applied R2.05 works the keyspace discipline this rests on.

the implementation (echo_mq)

EchoMQ.Keyspace.reserve/1 builds the {emq}: base, first-byte-disjoint from any queue's emq:, so the version fence at {emq}:version has a home no queue can occupy — and its own single-slot hashtag.

A reserved prefix is only safe if it cannot be reached from the application space. {emq}: earns that by a structural property — a different first byte — not by asking callers to avoid a name.

Recap — beside every queue, owned by none

The reserve is {emq}: — the cross-queue space, built by reserve/1, holding version_key/0 → {emq}:version. It is first-byte-disjoint from every per-queue emq: key, so a queue named emq cannot collide with it, and it is its own single-slot hashtag. The reserve is where the wire's own state lives. With the grammar, the slot, and the reserve in hand, the where of the protocol is complete; the next module reads the what — the record hash.

Next in The Protocol: The record hash — the job HASH at the job key and the field names that are part of the wire.

References

Where the reserve's store and the fence's claim are documented.

Sources

Related in this course