Gateway: Fixed a race condition on ReconnectOP

This commit is contained in:
diamondburned 2020-10-17 03:21:23 -07:00
parent 86795e42a6
commit 91ee92e9d5
2 changed files with 10 additions and 9 deletions

View File

@ -30,6 +30,11 @@ const (
GuildSubscriptionsOP OPCode = 14
)
// ErrReconnectRequest is returned by HandleOP if a ReconnectOP is given. This
// is used mostly internally to signal the heartbeat loop to reconnect, if
// needed. It is not a fatal error.
var ErrReconnectRequest = errors.New("ReconnectOP received")
func (g *Gateway) HandleOP(op *wsutil.OP) error {
switch op.Code {
case HeartbeatAckOP:
@ -47,13 +52,9 @@ func (g *Gateway) HandleOP(op *wsutil.OP) error {
// Server requests to reconnect, die and retry.
wsutil.WSDebug("ReconnectOP received.")
// We must reconnect in another goroutine, as running Reconnect
// synchronously would prevent the main event loop from exiting.
go g.Reconnect()
// Gracefully exit with a nil let the event handler take the signal from
// the pacemaker.
return nil
// Exit with the ReconnectOP error to force the heartbeat event loop to
// reconnect synchronously. Not really a fatal error.
return ErrReconnectRequest
case InvalidSessionOP:
// Discord expects us to sleep for no reason
@ -101,7 +102,7 @@ func (g *Gateway) HandleOP(op *wsutil.OP) error {
g.SessionID = ev.SessionID
}
// Throw the event into a channel, it's valid now.
// Throw the event into a channel; it's valid now.
g.Events <- ev
return nil

View File

@ -108,7 +108,7 @@ func (p *PacemakerLoop) startLoop() error {
// Handle the event
if err := p.handler(o); err != nil {
p.errorLog(errors.Wrap(err, "handler failed"))
return errors.Wrap(err, "handler failed")
}
}
}