whatyouhide / redix

Fast, pipelined, resilient Redis driver for Elixir. 🛍

Home Page:http://hexdocs.pm/redix

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

PubSub does not resubscribe to channel

paveltyk opened this issue · comments

When GenServer restarted, it never gets subscribed to channel again. How can I subscribe to channel again, once it goes to pending_subscriptions?

:sys.get_state(MyApp.Redix.PubSub)                             

{:connected,
 %Redix.PubSub.Connection{
   backoff_current: nil,
   connected_address: "localhost:6379",
   continuation: nil,
   last_disconnect_reason: nil,
   monitors: %{#PID<0.565.0> => #Reference<0.2331020780.1358430212.183205>},
   opts: [
     socket_opts: [],
     ssl: false,
     sync_connect: false,
     backoff_initial: 500,
     backoff_max: 30000,
     log: [
       disconnection: :error,
       failed_connection: :error,
       reconnection: :info
     ],
     exit_on_disconnection: false,
     timeout: 5000,
     host: 'localhost',
     port: 6379
   ],
   pending_subscriptions: %{{:channel, "my-channel"} => #MapSet<[#PID<0.565.0>]>},
   socket: #Port<0.111>,
   subscriptions: %{},
   transport: :gen_tcp
 }}

When my GenServer crashes, the Supervisor restarts it. However, it does not receive messages anymore, and remains in the state as :pending_subscriptions.

My supervision tree:

application.ex

defmodule MyApp.Application
  use Application

  def start(_type, _args) do
    children = [
      %{
        id: MyApp.Redix,
        start: {Redix, :start_link, [redis_uri, [name: MyApp.Redix]]},
        restart: :permanent,
        shutdown: 5_000,
        type: :worker
      },
      %{
        id: MyApp.Redix.PubSub,
        start: {Redix.PubSub, :start_link, [redis_uri, [name: MyApp.Redix.PubSub]]},
        restart: :permanent,
        shutdown: 5_000,
        type: :worker
      },
      MyApp.SystemPubSub
    ]
    opts = [strategy: :one_for_one, name: MyApp.Supervisor]
    Supervisor.start_link(children, opts)
  end
end

system_pub_sub.ex

defmodule MyApp.SystemPubSub do
  use GenServer

  def start_link(_opts) do
    GenServer.start_link(__MODULE__, :ok, name: __MODULE__)
  end

  # Callbacks

  @impl true
  def init(:ok) do
    Redix.PubSub.subscribe(MyApp.Redix.PubSub, @channel, self())
    {:ok, :ok}
  end

  @impl true
  def handle_info(:die, state) do
    {:ok} = {:error}
    {:noreply, state}
  end

  @impl true
  def handle_info({:redix_pubsub, _pubsub, _ref, :subscribed, %{channel: channel}}, state) do
    Logger.debug("The pub/sub listener is subscribed to the #{inspect(channel)} channel")
    {:noreply, state}
  end

  @impl true
  def handle_info({:redix_pubsub, _pubsub, _ref, :message, %{payload: message}}, state) do
    Logger.debug("Received message: #{inspect(message)}")
    {:noreply, state}
  end

  @impl true
  def handle_info(_, state) do
    {:noreply, state}
  end
end

Any advice, please?

commented

Happens to mee to, @whatyouhide what do you think?

Hey @paveltyk, I am not sure about what's going on here. I am not 100% sure I understand what you're doing to get in this situation.

When my GenServer crashes, the Supervisor restarts it. However, it does not receive messages anymore, and remains in the state as :pending_subscriptions.

When you say "When my GenServer crashes" do you mean MyApp.SystemPubSub? Because if MyApp.SystemPubSub crashes, Redix is not going to resubscribe it, it will have to resubscribe itself. Otherwise, what do you mean is crashing here?

@whatyouhide Yes, I meant MyApp.SystemPubSub. So when it crashes, supervisor restarts SystemPubSub, and it subscribes to a channel in the init callback. However, if I check MyApp.Redix.PubSub connection, my process remains in pending_subscriptions: pending_subscriptions: %{{:channel, "my-channel"} => #MapSet<[#PID<0.565.0>]>},. Does it make sense?

Yes, it was indeed a bug :) Fixed in master!

commented

cool, thanks @whatyouhide !

@whatyouhide confirm it's working now. One thing to note: GenServer now receive :subscribed message twice - https://github.com/paveltyk/pub-sub-issue-132/blob/master/lib/pub_sub/my_channel.ex#L20