Rheo.Backend.Redis (rheo v1.0.0)

Copy Markdown View Source

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

Child spec for the Redis connections (backend handle).

Default Redis handle name for the Rheo instance.

Blocks until new entries may be available for the group (ADR 025).

Functions

child_spec(opts)

@spec child_spec(keyword()) :: Supervisor.child_spec()

Child spec for the Redis connections (backend handle).

Arguments

  • opts — keyword options:
    • :name — handle / process name (default default_handle/0)
    • :url — redis://host:port/db (or rediss://… for TLS)
    • :host / :port / :database / :password — used when :url is 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.

default_handle()

@spec default_handle() :: atom()

Default Redis handle name for the Rheo instance.

Examples

iex> Rheo.Backend.Redis.default_handle()
Rheo.Redis

Returns

A process name atom (default Rheo.Redis).

wait(handle, opts \\ [])

@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 handle
  • opts — :timeout (ms, default 1000), :stream, :group, :partitions

Returns

:ok, or {:error, :backend_unavailable} / {:error, {:failed, cause}}.