hubertlepicki

hubertlepicki

Phoenix Sockets getting stuck at "closed", "connecting" or "disconnecting" state

I am using Phoenix with Apollo and @absinthe/socket-apollo-link to listen to GraphQL subscriptions. The users spend a lot of time on the app with tab open, without refreshing the page, often they have the app open for weeks.

Disconnects happen during that time, for various reasons. When we deploy new version is one case, but users’ devices go to sleep, they disconnect from wifi, or their network is having issues.

We have been getting reports, since about updating to Phoenix 1.6.4 on the page being “stuck”. I managed to reproduce it by just leaving the page open for 24 hours too, several WebSocket disconnection happened and, when I went to my computer the phoenixSocket.isConnected() was false and phoenixSocket.connectionStatus() was connecting.

Since then, I was able to reproduce the issue, fairly reliably by doing the following, with two hosts on my local network.

  1. I launch the app on Host A, on port 4000.
  2. From Host B, I open the SSH connection and port forwarding to Host A. So that port 4000 on Host B is forwarding TCP connection to Host B on port 4000.
  3. On Host B, I load the page over at localhost:4000. This goes to local forwarded port, hits Host A, renders page, connections establish properly.
  4. I disconnect wifi on Host B for 15 seconds or so. This is short enough so that SSH session doesn’t block, but the Phoenix socket disconnects.
  5. I turn on the wifi on Host B.
  6. I can see the page in Chrome on Host B being stuck. Connection is usually “closed”, but calling photnixSocket.connect() has no effect.

I can re-set the connection by first calling disconnect() and then immediately connect().

I suspect this may be an issue in Phoenix.js or somewhere in my code, but I wonder if someone else had similar issues?

Most Liked

hubertlepicki

hubertlepicki

Hey Chris, no, Chrome 96.

I suspect we had a websocket issue on production that since was resolved, and at the same time we did have the LongPoll fallback misconfigured. I bumped down the heartbeat from 30s to 5s, enabled LongPoll and I also monitor the socket this way every 5s:

function checkSocketWorks(phoenixSocket) {
  if (phoenixSocket.isConnected() == false) {
    connDropped = true;
    /* Phoenix.js seems to hang in 'disconnected', 'connecting', or 'disconnecting' states
     * when the network is unreliable but not totally down. In such case isConnected()
     * correctly returns false, but you cannot reconnect the connection before dropping it
     * manually, something disconnec() does */
    phoenixSocket.disconnect();
    phoenixSocket.connect();
  }
}

The above changes seem to have fixed it for us.

Do you want me to prepare either a video / isolated code example to reproduce the issue? I suspect it may be some race condition in the socket JS implementation that we’re hitting.

Where Next?

Popular in Questions Top

Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
vac
Hi, I’m quite new in Elixir and I’m trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and I...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
dotdotdotPaul
Okay, I’m having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I’m sure I’...
New

Other popular topics Top

New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
274 41989 114
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 43757 214
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
saif
Hello everyone, Long time lurker first time poster here. I’ve recently begun working on Elixir full-time again! :raised_hands: It’s been...
New
boundedvariable
I am going through the kafka architecture. All the features what the kafka is providing are already in Erlang. I would like hear your opi...
New
jaysoifer
Is there a way to rollback a specific migration and only that one (“skipping” all the other ones)? Would mix ecto.rollback -v 200809061...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement