Current section
Files
Jump to
Current section
Files
lib/stream.ex
defmodule Redix.Stream do
@moduledoc """
`Redix.Stream` exposes an API for producing to redis streams, as well
consuming from those streams (via a process called a `Consumer`).
"""
alias Redix.Stream.ConsumerSup
@type redix :: pid() | atom()
@type t :: String.t()
@type handler :: {module(), atom(), list(any())}
@doc """
Produces a new single message into a Redis stream.
Note: For values which are not strings, each of those values will be
converted into a string via `to_string/1`.
## Examples
iex> {:ok, msg_id} = Redix.Stream.produce(:redix, "topic", %{"temperature" => 55})
iex> Enum.count(String.split(msg_id, "-"))
2
"""
@spec produce(redix, t, %{String.t() => any()}) :: {:ok, String.t()} | {:error, any()}
def produce(redix, stream, key_values) do
redis_command =
key_values
|> Enum.reduce(["*", stream, "XADD"], fn {k, v}, acc ->
[to_string(v) | [k | acc]]
end)
|> Enum.reverse()
case Redix.command(redix, redis_command) do
{:ok, id} when is_binary(id) -> {:ok, id}
{:error, error} -> {:error, error}
end
end
@doc """
Provides a supervisable specification for a consumer which consumes
from the given topic or topics.
## Examples
iex> Redix.Stream.consumer_spec(:redix, "topic", fn msg -> msg end)[:id]
Redix.Stream.ConsumerSup
iex> Redix.Stream.consumer_spec(:redix, "topic", {Module, :function, [:arg1, :arg2]}, sup_id: MyConsumer)[:id]
MyConsumer
iex> Redix.Stream.consumer_spec(:redix, "topic", {Module, :function, [:arg1, :arg2]}, sup_restart: :transient)[:restart]
:transient
"""
@spec consumer_spec(redix, t, function() | handler(), keyword()) :: Supervisor.child_spec()
def consumer_spec(redix, stream, callback, opts \\ []) do
ConsumerSup.child_spec([redix, stream, callback, opts])
end
end