SwiftcordApp/Swiftcord

Heartbeat timers piling up, eventually causing disconnection

Closed this issue · 3 comments

Describe the bug
When the app remains in the background for a long time, macOS "suspends" network activity, including WebSockets. This causes heartbeat ACKs to go missing, and the connection will eventually be terminated due to the threshold of pending heartbeat ACK being exceeded. In such a scenario, another WebSocket should be opened, and the session resumed. Unfortunately, a bug causes the connection to be immediately terminated again right after reconnection, which I suspect is due to the heartbeat timers not being stopped properly and the pending ACKs not being reset.

To Reproduce

  1. Keep the app open in the background for a long time
  2. Observe how the connection is broken and the socket being closed immediately after opening

Expected behavior

The socket reconnects and resumes in such a scenario.

Logs

https://gist.github.com/cryptoAlgorithm/ba1a390899f41d28b71d6bf027266815

Additional context

There were also a few connection drops due to sleep/internet connection loss, might have made the issue more serious.

This issue appears to be caused by the heartbeat timers not being invalidated properly when the gateway reconnects.

This appears to be resolved by commit 7eccca1, might reopen if necessary.

This title better represents the actual issue, which is caused by an additional heartbeat timer being started every time the connection reconnects, but the old ones not being invalidated properly. Eventually 20 or more timers pile up, and heartbeats are sent before discord can even respond with an ACK. This slowly causes the missing ACK tolerance to be exceeded, causing the connection to be terminated. However, every time the connection reconnects more timers pile up, so the connection rapidly reconnects and disconnects.