jonnify·redis /redis-patterns/overview/patterns-become-protocol/the-four-layers

R0.3.1 · Patterns become protocol — dive 1

The four layers.

Five layers, one boundary. Below the boundary sits the owned protocol — the grammar and the versioned bundle; above it, each runtime writes its own connector and API. The boundary is held by the version fence, not by a pinned commit.

Grounding: content/bcs3.3.md (the claim script, verbatim) · bcs3.2.md (the script is the contract) · bcsA.md (the connector gate, Valkey).

The stack, engine up. Select a layer to read its scope and status.
L4 · runtime API L3 · the connector — the boundary · held by the version fence — L2 · the bundle L1 · the grammar L0 · Valkey
readout · Select a layer to read its scope and whether it belongs to the owned protocol.

Static verdicts — L4 → varies per runtime · L3 → varies per runtime, gated PASS 8/8 · L2 → owned, versioned · L1 → owned, versioned · L0 → external, an enforced conformance gate.

§1

Five layers, engine up

emq.md · bcsA

L0 is Valkey — the engine, external to EchoMQ, and not merely a default: the conformance truth row runs on Valkey, current stable line, and the committed gate record was taken against live Valkey 9.1.0. L1 is the grammar and the sets: every per-queue key parses as emq:{q}:<type>, the job position carries a branded id, and four sorted sets carry the lifecycle. L2 is the versioned bundle: six Lua scripts, eight verbs, every key declared in KEYS[] or derived from a declared root.

L3 is the connector — per runtime: RESP encoding in one pass, pipelining as the primitive, EVALSHA-first dispatch that loads a script’s source exactly once on a NOSCRIPT miss. L4 is the runtime API — the eight verbs a caller uses: enqueue, browse, pending_size, claim, complete, retry, promote, reap. L3 and L4 vary per runtime; the layers below them are the owned protocol.

LayerScopeStatus
L4 · runtime APIthe eight verbs a caller invokesvaries per runtime
L3 · the connectorRESP, pipelining, EVALSHA-first; reads the fence at every connectvaries per runtime; gated PASS 8/8
L2 · the bundlesix Lua scripts, eight verbs; declared-or-rooted keysowned · versioned behind the fence
L1 · the grammaremq:{q}:<type> · the three-field hash · the four sorted setsowned · versioned behind the fence
L0 · Valkeythe engineexternal — an enforced conformance gate
§2

One script, one transition — the claim, verbatim

content/bcs3.3.md · verbatim

The whole layered argument compresses into one L2 script. The claim script pops the lex-oldest pending id, increments attempts, stamps the lease on the server’s clock, and returns the job — atomically, as one unit:

content/bcs3.3.md · the claim script · verbatimfrozen
local popped = redis.call('ZPOPMIN', KEYS[1])
if #popped == 0 then return {} end
local id = popped[1]
local jk = ARGV[1] .. id
local att = redis.call('HINCRBY', jk, 'attempts', 1)
redis.call('HSET', jk, 'state', 'active')
local t = redis.call('TIME')
local now = t[1] * 1000 + math.floor(t[2] / 1000)
redis.call('ZADD', KEYS[2], now + tonumber(ARGV[2]), id)
return {id, redis.call('HGET', jk, 'payload'), att}

Each layer is visible in those ten lines. ZPOPMIN off the pending set and ZADD onto the active set are L1 moves over the grammar. The script itself is L2 — one atomic transition. The EVALSHA call that dispatched it is L3. And the claim verb the caller invoked is L4. The clock is the server’s: TIME inside the script means leases never read client skew.

Notes on ValkeyTIME inside a write script is sound here: the engine freezes the clock for the script’s duration and replicates effects rather than the script text, so the lease stamp reads one stable now — valkey.io/topics/replication.

§3

What stays the same — the script is the contract

content/bcs3.2.md · How · bcsA

Across runtimes, nothing ports because nothing needs to: the script is the contract. The same source string yields the same SHA1, and any client on any runtime that loads it speaks identical semantics — same pop, same token mint, same lease arithmetic. What varies is only the plumbing above the boundary: an Elixir connector pattern-matches typed replies; a Go consumer is a loop around the same EVALSHA calls.

Place the fact. Select a fact from the committed record; the readout names the layer it lives in.
readout · Select a fact. Each one is committed, and each one lives in exactly one layer of the stack.

Static verdicts — TIME in the script → L2 (the server’s clock) · script_loads=1 → L3 (the dispatch) · emq:{orders}:pending → L1 (the grammar) · Valkey → L0 (the engine) · claim → complete → L4 (the consumer’s contract).

the application · the L3 dispatch, gated

The connector gate at the boundary

The dispatch that carries every script is measured, not assumed — the committed record against live Valkey:

content/bcsA.md · the connector gate · the script path and the pipelinefrozen
script_loads                  1              ← exactly one NOSCRIPT load
pipelined EVALSHA             161192 ops/s   ← declared-keys law at speed
10000-command pipeline        returned 1..10000 in order
gate record                   PASS 8/8
the pattern

Put the rules that must agree below a boundary, and the plumbing that may differ above it. The shared part becomes the protocol; the plumbing stays a local choice.

its EchoMQ application

The claim is one Lua script over the braced grammar — same bytes, same SHA1, same semantics from any connector. The runtimes differ only in how they dispatch it.

A pattern becomes a protocol when the agreement lives below the boundary and the language stays above it. One claim script, one grammar — any runtime.

§4

References

sources · related

Sources

Related in this course