I want to open a Redis connection and I have written a code something like this for persistent connection within the system. The way I'm doing this I'm calling a handle_info function which uses the Redix client. I have defined the dependency for redix
def start_link(opts \\ [name: __MODULE__]) do
GenServer.start_link(__MODULE__, nil, Keyword.merge(opts, name: __MODULE__))
end
@impl true
def init(_) do
send(self(), :connect)
{:ok, nil}
end
@impl true
def handle_info(:connect, _conn) do
host = "redis://localhost:6379/3"
case Redix.start_link(host) do
{:ok, conn} ->
IO.inspect(conn)
Process.monitor(conn.pid)
{:noreply, conn}
{:error, _} ->
Process.send_after(self(), :connect, @reconnect_interval)
{:noreply, nil}
end
end
I call with redix client to the server with handle info. When I use the PID to set a key in Redis something like this
Redix.command!(conn, ["SET", "queue"])
I get this error
[error] GenServer Zuppler.Utils.Redis.Connection terminating
** (RuntimeError) attempted to cast GenServer Zuppler.Utils.Redis.Connection but no handle_cast/2 clause was provided
(zuppler_utils 0.1.12) lib/gen_server.ex:824: Zuppler.Utils.Redis.Connection.handle_cast/2
(stdlib 3.17.1) gen_server.erl:695: :gen_server.try_dispatch/4
(stdlib 3.17.1) gen_server.erl:771: :gen_server.handle_msg/6
(stdlib 3.17.1) proc_lib.erl:226: :proc_lib.init_p_do_apply/3
Last message: {:"$gen_cast", {:pipeline, [["llen", "list_name"]], {#PID<0.694.0>, #Reference<0.884395455.1828454401.122583>}, 5000}}
State: #PID<0.801.0>
** (EXIT from #PID<0.694.0>) shell process exited with reason: an exception was raised:
** (RuntimeError) attempted to cast GenServer Zuppler.Utils.Redis.Connection but no handle_cast/2 clause was provided
(zuppler_utils 0.1.12) lib/gen_server.ex:824: Zuppler.Utils.Redis.Connection.handle_cast/2
(stdlib 3.17.1) gen_server.erl:695: :gen_server.try_dispatch/4
(stdlib 3.17.1) gen_server.erl:771: :gen_server.handle_msg/6
(stdlib 3.17.1) proc_lib.erl:226: :proc_lib.init_p_do_apply/3
You already have
IO.inspect(conn)which must have shown youconnis apid. Right in the next line you try to callconn.pidwhich is treated as a function call, which maps to:erlang.apply(#PID<0.1075.0>, :pid, [])and obviously raises. The following would most likely do.Sidenote: use
GenServer.handle_continue/2callback instead of sending the message toselfwhich exists for exactly this kind of initialization.Also, one usually starts
Redixwithin the application supervision tree as described in the documentation.