# `Rheo.Backend.Redis`
[🔗](https://github.com/thanos/rheo/blob/v1.0.0/lib/rheo/backend/redis.ex#L3)

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`.

# `child_spec`

```elixir
@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`

```elixir
@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`

```elixir
@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}}`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
