8000 fix(gateway): don't hold statusMu while sending by thomas-vilte · Pull Request #646 · disgoorg/disgo · GitHub
[go: up one dir, main page]

Skip to content

fix(gateway): don't hold statusMu while sending - #646

Merged
topi314 merged 1 commit into
disgoorg:masterfrom
thomas-vilte:fix/gateway-send-lock-order
Nov 6, 2026
Merged

topi314 merged 1 commit into
disgoorg:masterfrom
thomas-vilte:fix/gateway-send-lock-order

Conversation

@thomas-vilte
Copy link
Copy Markdown
Contributor

Send holds statusMu while it calls sendInternal, which takes connMu. CloseWithCode and open take them the other way around, connMu first and then statusMu. If the connection drops while something is sending, listen calls CloseWithCode and the two goroutines end up waiting on each other forever. After that every Send, Status() and the reconnect block too, so the bot stays offline until it's restarted.

This happened to my bot last night. The type 20 channel issue (fixed by #644/#645) made it reconnect ~300 times in 40 minutes, one of those closes landed while SetPresence was sending, and it stayed stuck for 18 hours. The goroutine profile had these two (line numbers from master):

gateway.(*gatewayImpl).listen
  gateway.(*gatewayImpl).CloseWithCode   gateway.go:381   holds connMu, waits for statusMu

bot.(*Client).SetPresence
  gateway.(*gatewayImpl).Send            gateway.go:399   holds statusMu
  gateway.(*gatewayImpl).sendInternal    gateway.go:408   waits for connMu

Send now reads the status through Status() and releases the lock before sending. If the status changes in between, sendInternal still checks g.conn under connMu and returns ErrShardNotConnected.

To confirm it, I ran Send and CloseWithCode concurrently 2000 times: master hung in 6 of 8 runs, with this change it never did. I didn't add that as a test since it depends on timing. The test checks the lock order directly instead: the rate limiter runs inside sendInternal with connMu held, and from there statusMu has to be free.

@topi314
topi314 merged commit 7f6ba3a into disgoorg:master Nov 6, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

2 participants

0