mobileoverlord/phoenix_client

Rejoining channel after server restart

Closed this issue · 3 comments

coop commented

I have the following situation:

  1. Server creates channel
  2. Nerves Device joins channel
  3. Server terminates
  4. Nerves Device receives phx_error message
  5. Nerves Device tries to reconnect but receives {:error, :already_joined, pid} error
  6. Server is not aware of Nerves Device and Nerves Device is not connected to channel

This behaviour is incorrect as the server has been restarted and has no connected clients. It looks like PhoneixClient.Socket is storing a list of already connected channels here which hasn't been cleaned out when phx_error was received.

To "fix" this I have the following code:

  defp join(state) do
    case Channel.join(state.socket, state.topic, state.join_params) do
      # other matches removed for clarity

      {:error, {:already_joined, _pid}} ->
        state = %{state | channel: pid}
        # Can't use `Channel.leave(state.channel)` because it stops the process
        PhoenixClient.Socket.channel_leave(state.socket, self(), state.topic)
        Process.send_after(self(), :join, 5000)
        {:noreply, state}
    end
  end

I'm not sure if there is a generic solution for this. Thoughts?

It certainly seems like a bug. Since we are passing the responsibility of rejoining the channel to the caller, the socket should clear out the channels from its state on a disconnect event.

Can you check out the branch rel-v0.8.0 and let me know if this fixes your issue? I added a test to verify that this was happening and I can see that it should fix it.

Fixed in 0.8.0