Redis Streams implementation of Rheo.Backend (ADR 026).
Requires {:redix, "~> 1.5"} in your dependencies and Redis 6.2+.
Prefer the Rheo facade for application code. The opaque handle is the
Redix process name (or pid) started via child_spec/1.
Model C
One Redis STREAM per Rheo partition. Rheo keeps the portable
event.sequence in a counter and a sequence → entry id sorted set; the
lease receipt is the Redis entry id (ADR 021). Redis owns delivery
mechanics (consumer groups, pending list, XCLAIM reclaim), Rheo owns
semantics (fencing, attempts, dead-letter, contiguous frontier).
Fencing is stronger than XACK: every claim writes a fence hash keyed by
entry id holding the current lease_id. A settle call validates the fence
before XACK, so a stale holder can never acknowledge someone else's claim.
Keys
See Rheo.Backend.Redis.Keys. Everything lives under rheo:{handle}:, so
several instances may share one Redis database.
Supervision example
children = [
{Rheo,
name: MyRheo,
backend: {Rheo.Backend.Redis, name: MyRheo.Redis, url: "redis://localhost:6379"}}
]child_spec/1 starts two Redix connections: the handle itself and a
….Waiter connection used only by wait/2, so a blocking read never
stalls commands on the main connection. :pool_size is not supported in
v0.9.
Query cost
secondary_indexes: false: query/2 walks the partition streams and
filters in the adapter. Bound queries with :after_sequence /
:until_sequence on large streams.
Callback semantics are documented on Rheo.Backend.
Summary
Functions
@spec child_spec(keyword()) :: Supervisor.child_spec()
Child spec for the Redis connections (backend handle).
Arguments
opts— keyword options::name— handle / process name (defaultdefault_handle/0):url—redis://host:port/db(orrediss://…for TLS):host/:port/:database/:password— used when:urlis absent- other options are forwarded to
Redix.start_link/1
Examples
iex> spec = Rheo.Backend.Redis.child_spec(name: :demo_redis, url: "redis://localhost:6379")
iex> {spec.id, spec.type}
{{Rheo.Backend.Redis, :demo_redis}, :supervisor}Returns
A supervisor child spec map.
@spec default_handle() :: atom()
Default Redis handle name for the Rheo instance.
Examples
iex> Rheo.Backend.Redis.default_handle()
Rheo.RedisReturns
A process name atom (default Rheo.Redis).
@spec wait(Rheo.Backend.handle(), keyword()) :: :ok | {:error, term()}
Blocks until new entries may be available for the group (ADR 025).
Runs XREAD BLOCK from each assigned partition's group cursor on a
dedicated Redix connection, so a blocking wait never stalls commands on the
handle. Returns :ok on both a wakeup and a timeout: the caller must still
fetch. Without :stream / :group hints there is nothing to watch, so the
call sleeps for :timeout and returns :ok, leaving polling in charge.
Arguments
handle— backend handleopts—:timeout(ms, default1000),:stream,:group,:partitions
Returns
:ok, or {:error, :backend_unavailable} / {:error, {:failed, cause}}.