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 Jul 11, 2024. It is now read-only.
When connecting to Discord with a large guild membership the heartbeat process will continually reconnect due to not receiving heartbeat ACKs. This appears to be caused by Discord prioritizing GUILD_CREATE events which are sent as a synchronization process after the READY event.
Expected behavior
Disgord should not trigger a reconnect attempt during guild synchronization even if heartbeat ACKs are delayed.
Error messages
This appears as normal heartbeat timeout errors after the initial connection setup is performed and the READY event has been received.
Desktop (please complete the following information):
Golang version: v16.6.6
Using Go modules? yes
Disgord version? 0.27.3
Connected to the gateway before using REST methods? yes
Additional context
I did some testing with event flow and found that Discord will block heartbeat ACKs during the guild synchronization phase of a new connection which leads to the timeout issues described above.
What appears to be happening is that a stream of GUILD_CREATE events will be received after the READY event. During this time a heartbeat request will be sent but no ACK will be received which triggers the reconnect logic. If the reconnect logic is disabled, multiple heartbeat ACKs are received after the guild synchronization is complete indicating that they are delayed.
I tested some possible solutions but didn't find any of them satisfactory:
Set lastHeartbeatAck for every GUILD_CREATE event. This resolves the issue by keeping the ACK timestamp fresh as events are received during guild synchronization but is philosophically wrong.
Set a flag that will ignore missed heartbeats after the READY event until the first ACK is received. This would effectively turn off the reconnect logic until after guild synchronization is complete but offers no connection tracking during this process.
Use a timer and set of flags to detect the guild synchronization process and only turn on heartbeats after it is complete. This is a more complex solution and technically still suffers from the drawback in solution 2.
One other issue is that you cannot turn heartbeats off completely or you will get read errors from the receiver which also trigger a reconnect. I haven't had the time to trace it down, but I'm assuming that Discord is dropping the websocket connection if no traffic is sent periodically. This means that even if heartbeat ACKs are ignored, heartbeat requests still need to be sent to prevent this error from occurring.
So I'm kind of at a loss as to what a proper solution should be. I'd be happy to post a PR for this if something reasonable could be suggested. I thought for now the first step would be to report it and go from there.
The text was updated successfully, but these errors were encountered:
Describe the bug
When connecting to Discord with a large guild membership the heartbeat process will continually reconnect due to not receiving heartbeat ACKs. This appears to be caused by Discord prioritizing
GUILD_CREATE
events which are sent as a synchronization process after theREADY
event.Expected behavior
Disgord should not trigger a reconnect attempt during guild synchronization even if heartbeat ACKs are delayed.
Error messages
This appears as normal heartbeat timeout errors after the initial connection setup is performed and the
READY
event has been received.Desktop (please complete the following information):
Additional context
I did some testing with event flow and found that Discord will block heartbeat ACKs during the guild synchronization phase of a new connection which leads to the timeout issues described above.
What appears to be happening is that a stream of
GUILD_CREATE
events will be received after theREADY
event. During this time a heartbeat request will be sent but no ACK will be received which triggers the reconnect logic. If the reconnect logic is disabled, multiple heartbeat ACKs are received after the guild synchronization is complete indicating that they are delayed.I tested some possible solutions but didn't find any of them satisfactory:
Set
lastHeartbeatAck
for everyGUILD_CREATE
event. This resolves the issue by keeping the ACK timestamp fresh as events are received during guild synchronization but is philosophically wrong.Set a flag that will ignore missed heartbeats after the
READY
event until the first ACK is received. This would effectively turn off the reconnect logic until after guild synchronization is complete but offers no connection tracking during this process.Use a timer and set of flags to detect the guild synchronization process and only turn on heartbeats after it is complete. This is a more complex solution and technically still suffers from the drawback in solution 2.
One other issue is that you cannot turn heartbeats off completely or you will get read errors from the receiver which also trigger a reconnect. I haven't had the time to trace it down, but I'm assuming that Discord is dropping the websocket connection if no traffic is sent periodically. This means that even if heartbeat ACKs are ignored, heartbeat requests still need to be sent to prevent this error from occurring.
So I'm kind of at a loss as to what a proper solution should be. I'd be happy to post a PR for this if something reasonable could be suggested. I thought for now the first step would be to report it and go from there.
The text was updated successfully, but these errors were encountered: