You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Apr 14, 2023. It is now read-only.
After restarting the backend, our client ends up in a continuous reconnection loop.
Our backend is using gqlgen for its GraphQL API. The current version implements keep alive, but only sends the "KA" messages on a regular basis after the connection has been set up, default is every 25 seconds. So there is no "KA" directly after the "ACK" only after 25 seconds.
The SubscriptionClient in our client is configured to with reconnect: true and to use an extended ws implementation. ws is only extended so we can pass an Agent with certificates to the constructor of ws, there are no other changes to ws logic.
The flow causing our issue as far as I have analyzed it is close to the following:
The client, i.e. SubscriptionClient, connects to the backend, that is running on the same computer, by creating a new WebSocket, ws, and adds an event listener to the WebSockets onclose event (as well as other events)
Client receives "ACK"
After 25 seconds the client receives the first "KA" and starts the CheckConnectionInterval that is triggered every 30 seconds from now on
A about 10 seconds after the first "KA" I restart the backend
The WebSocket detects this and emits a close event that triggers the onclose event handler
The client calls close on the WebSocket and sets it reference to null, but it does not clear the event listeners
The client reconnects to the backend, creates and sets up a new WebSocket. Let's call this one "B"
Client receives "ACK"
Before the "KA" message is received the client triggers the check connection logic, that detects that it has not received a "KA" message and thus closes WebSocket "B" as in 6.
WebSocket "B" initiates the closing handshake and sets a timeout that destoys the socket after 30 seconds if the closing handshake fails, i.e. does not get a close event from the socket. And this handshake fails, but I have not figured out why or how. The onclose is not triggered yet.
The client reconnects to the backend, creates and sets up yet another new WebSocket. Let's call it "C".
Client receives "ACK"
For the sake of simplicity here let's assume "KA" is received so the check connection interval does not close the connection.
However the WebSocket "B"'s closing handshake timeout now triggers and destroys it's socket
Since the client has not cleaned up the event listeners from WebSocket "B", WebSocket "B" will now trigger the onclose and thus the client will now close WebSocket "C"
This combination of late "KA" messages, the failure of the WebSocket's closing handshake and the event listeners not being properly cleaned up causes our client to end up in a continuous reconnection loop.
I'm reproducing the loop with step 4 being client loses internet and @tretne PR fix works. I'm monkey patching the client for now :/. It needs to be merged asap
After restarting the backend, our client ends up in a continuous reconnection loop.
Our backend is using
gqlgen
for its GraphQL API. The current version implements keep alive, but only sends the "KA" messages on a regular basis after the connection has been set up, default is every 25 seconds. So there is no "KA" directly after the "ACK" only after 25 seconds.The
SubscriptionClient
in our client is configured to withreconnect: true
and to use an extendedws
implementation.ws
is only extended so we can pass anAgent
with certificates to the constructor ofws
, there are no other changes tows
logic.The flow causing our issue as far as I have analyzed it is close to the following:
SubscriptionClient
, connects to the backend, that is running on the same computer, by creating a new WebSocket,ws
, and adds an event listener to the WebSocketsonclose
event (as well as other events)CheckConnectionInterval
that is triggered every 30 seconds from now onclose
event that triggers theonclose
event handleronclose
is not triggered yet.onclose
and thus the client will now close WebSocket "C"This combination of late "KA" messages, the failure of the WebSocket's closing handshake and the event listeners not being properly cleaned up causes our client to end up in a continuous reconnection loop.
client deps:
backend deps:
The text was updated successfully, but these errors were encountered: