module Redix.Utils is not available

I am trying Redis PubSub using the Redix library but it throws the following error:

iex(1)> {:ok, pubsub} = Redix.PubSub.start_link([])
** (UndefinedFunctionError) function Redix.Utils.sanitize_starting_opts/1 is undefined (module Redix.Utils is not available)
    Redix.Utils.sanitize_starting_opts([])
    (redix_pubsub) lib/redix/pubsub.ex:290: Redix.PubSub.start_link/1

This is my mix.exs deps():

[
      {:redix, ">= 0.0.0"},
      {:redix_pubsub, ">= 0.5.0"},
    ]

Any ideas what I am missing here?

How have you started the iex session? And what does your app function look like in mix.exs?

Yes. I have started iex session.

This is my mix.exs:

  def application do
    [
      extra_applications: [:logger],
      mod: {Sg.Application, []}
    ]
  end

Not “if”, but “how” :wink:

Anyway, I just learned that :redix < 0.9.0 came without pubsub, but since >= 0.9.0 the pubsub module seems to be integrated.

So I assume you have some version conflict.

Please check your mix.lock what version of redix is actually loaded.

Maybe best is to update redix to ~> 0.9 and remove dependency on :redix_pubsub.

These are the versions I am using:

  redix 0.9.3
  redix_pubsub 0.5.0

Yeah. Either use [{:redix, "~> 0.8.0"}, {:redix_pubsub, "~> 0.5.0"}] or [{:redix, "~> 0.9.0"}].

:redix_pubsub specified :redix ~> 0.8 so from a mix point of view 0.9.x is compatible, but it actually isn’t.

Thanks. This worked {:redix, "~> 0.9"}

I am trying to get some worker processes to subscribe to channel messages:
Redix.PubSub.subscribe(pubsub, "my_channel", self()). supervisor gets all the messages if I put this code in the supervisor. Anyway I can get child processes of a supervisor to receive these?

Provide a different subscriber than self()?

Yes. That worked. I had to store the pubsub connection object in a GenServer and then push messages to a set of workers to process. This pattern allows me to add more subscribers at any time. Here is the working code:

def init(args) do
    {:ok, pubsub} = Redix.PubSub.start_link()
    Sg.Subscribers.update_pubsub_link(pubsub)
    DynamicSupervisor.init(strategy: :one_for_one)
  end

  def add_channel_reader() do
    {:ok, pid} = DynamicSupervisor.start_child(@me, Sg.ChannelReader)
    pubsub = Sg.Subscribers.get_pubsub_link
    Redix.PubSub.subscribe(pubsub, "my_channel", pid)
  end
1 Like