1
0
Fork 0
mirror of https://github.com/diamondburned/arikawa.git synced 2024-12-02 11:52:56 +00:00

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 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 { func (g *Gateway) HandleOP(op *wsutil.OP) error {
switch op.Code { switch op.Code {
case HeartbeatAckOP: case HeartbeatAckOP:
@ -47,13 +52,9 @@ func (g *Gateway) HandleOP(op *wsutil.OP) error {
// Server requests to reconnect, die and retry. // Server requests to reconnect, die and retry.
wsutil.WSDebug("ReconnectOP received.") wsutil.WSDebug("ReconnectOP received.")
// We must reconnect in another goroutine, as running Reconnect // Exit with the ReconnectOP error to force the heartbeat event loop to
// synchronously would prevent the main event loop from exiting. // reconnect synchronously. Not really a fatal error.
go g.Reconnect() return ErrReconnectRequest
// Gracefully exit with a nil let the event handler take the signal from
// the pacemaker.
return nil
case InvalidSessionOP: case InvalidSessionOP:
// Discord expects us to sleep for no reason // Discord expects us to sleep for no reason
@ -101,7 +102,7 @@ func (g *Gateway) HandleOP(op *wsutil.OP) error {
g.SessionID = ev.SessionID 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 g.Events <- ev
return nil return nil

View file

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