Skip to content

Report back on connect/disconnect#26

Closed
paulstatezny wants to merge 1 commit intomobileoverlord:masterfrom
paulstatezny:report-back-connect-and-disconnect
Closed

Report back on connect/disconnect#26
paulstatezny wants to merge 1 commit intomobileoverlord:masterfrom
paulstatezny:report-back-connect-and-disconnect

Conversation

@paulstatezny
Copy link
Copy Markdown
Contributor

@paulstatezny paulstatezny commented Jan 24, 2020

Hey @mobileoverlord, first off -- thanks again for this library. 😃

This is a feature request to add some kind of mechanism to report back whenever connect/disconnect happens.

The use case is that our application connects to another Phoenix application on startup and joins some channels immediately. If there is a disconnection, it's great that phoenix_client automatically retries under the hood. But whenever the connection is reestablished, there's currently no way to be notified. I would like to be notified so that I can immediately re-join the channels.

Is that something you'd be open to? I'd be glad to re-work the code in any way if there's a better API and/or write tests. I don't think report_back_pid is a wonderful name, but it's the best I could think of in the moment. 😄

@paulstatezny
Copy link
Copy Markdown
Contributor Author

paulstatezny commented Jan 24, 2020

Come to think of it, looks like #25 addresses this in a more holistic way. 🤔

Edit: Maybe not... doesn't seem that #25 provides a mechanism that enables auto-re-join channels on connect.

@rockneurotiko
Copy link
Copy Markdown

Hi!

Our use-case was similar than yours, when the channel disconnects I want them to reconnect again, but I know that it's not needed to reconnect always, that's why in #25 it just closes the process and your process receives that event too, so you can handle it like you want (reconnect, or stop everything, log it to some reporting platform, ...)

We've been using the code of the PR for weeks on production, and it seems to be working correctly, and also we don't see

{:ok, socket} = Socket.start_link(config)
wait_for_socket(socket)
assert_received {:phoenix_client, :connected}
end
Copy link
Copy Markdown
Contributor Author

@paulstatezny paulstatezny Jan 24, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried many ways of testing the :disconnected message, but there's some complicated OTP stuff going on here and it interacts with (and breaks) the other tests even though async is false. 😭

@rockneurotiko
Copy link
Copy Markdown

rockneurotiko commented Jan 29, 2020

Ok, now I understand this PR, and it's different than #25
I really like being able to receive the message to know if the socket is disconnected/connected, right now I'm checking every X time, so that's where I'm able to re-subscribe, basically I have to keep track if it's connected and/or subscribed, and then based on that, it act accordingly.

Edit: I'm thinking if maybe it makes sense to use the caller pid on PhoenixClient.Channel, and just creates a new type of message that notifies about the socket connection

@paulstatezny
Copy link
Copy Markdown
Contributor Author

paulstatezny commented Jan 29, 2020

@rockneurotiko Yeah, my initial idea was using the caller pid. But I didn't like that that would force the caller to implement handle_info for these messages or crash.

Perhaps a better model would be a boolean:

Socket.start_link(report_connection_events: true)

Or something like that. And it would send to the caller.

@djthread
Copy link
Copy Markdown

djthread commented Feb 4, 2020

Nice! First, thank you Justin for this sweet library! Second, thanks, @paulstatezny, for this PR. It seems to be exactly what we need.

Once reconnected after dropping, the socket is no longer subscribed to the channels as originally joined, so I would need to rejoin them. The problem is, there doesn't seem to be any feedback as to when to do this! I thought I was missing something until I found this PR...

Is something like this going to be the best way to get the channels rejoined, or could it possibly be a reasonable idea for the library to automatically rejoin the channels?

Cheers & Thanks!

@paulstatezny
Copy link
Copy Markdown
Contributor Author

Thanks for chiming in @djthread!

Some thoughts about the auto-join vs specify-pid vs send-to-caller options:

  • Phoenix.js does not auto rejoin. It provides low level primitives but does not make assumptions about higher level things like whether you want to rejoin on auto-reconnect. For consistency, the Elixir client should perhaps follow this model.

  • Also in the vein of consistency with Phoenix.js: The JS library allows listening to connection events via onOpen/onClose/onError functions where you send a callback function. This library could follow a similar convention, although perhaps that's more "JavaScript-ey". Message passing feels more idiomatic of Elixir to me.

@djthread
Copy link
Copy Markdown

djthread commented Feb 4, 2020

That all sounds good to me. I will probably soon be trying to make use of your branch, so thanks for contributing it!

@paulstatezny
Copy link
Copy Markdown
Contributor Author

paulstatezny commented Feb 4, 2020

Turns out I was wrong here:

Phoenix.js does not auto rejoin.

🤦‍♂

See:

https://github.com/phoenixframework/phoenix/blob/master/assets/js/phoenix.js#L383

So I'm rethinking this. Rather than reporting back, I think the library should auto-rejoin on reconnect.

@mobileoverlord How do you feel about that? I'd be glad to put in a PR.

@rockneurotiko
Copy link
Copy Markdown

You are totally right! I thought too that it doesn't make the re-join! But they even say it on the documentation:

  • onError hooks

  • onError hooks are invoked if the socket connection drops, or the channel
  • crashes on the server. In either case, a channel rejoin is attempted
  • automatically in an exponential backoff manner.
  • onClose hooks

  • onClose hooks are invoked only in two cases. 1) the channel explicitly
  • closed on the server, or 2). The client explicitly closed, by calling
  • channel.leave()

I will change my PR to do it, but it will still send the message up, just like on the javascript client they call the callback, so the process that started it still have control over it.

@cybrox
Copy link
Copy Markdown

cybrox commented Mar 17, 2020

First of all, thanks for the work put into the library and this PR.

I have to admit, I am a bit stunned by the fact that there seems to be no Phoenix channel client library for Elixir itself that handles the most important concern, a stable connection, properly. In my opinion, the inclusion of this PR is absolutely essential, as is the implementation of the correct channel re-join behaviour proposed in #25.

I am currently rewriting an embedded device software with the biggest focus being a stable connection to the server. So far, it is using PhoenixChannelClient and a lot of manual re-join handling, so I wanted to replace that with a more elegant solution.

Sadly, at the moment, it seems like the relevant PRs here are in limbo? I can fork the repo and get a working version, sure, but I would be interested to learn what keeps this library from moving forward at the moment?

@paulstatezny paulstatezny changed the title Report back to a given PID on connect/disconnect Report back on connect/disconnect May 13, 2020
@paulstatezny
Copy link
Copy Markdown
Contributor Author

Closing this because it's probably never going to be merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants