1
0
Fork 0
mirror of https://github.com/diamondburned/arikawa.git synced 2025-11-22 04:23:39 +00:00

Fixed bug where reconnect would fail

This commit is contained in:
diamondburned (Forefront) 2020-01-17 23:40:44 -08:00
parent 7f5a470024
commit 971c162d33
4 changed files with 26 additions and 11 deletions

View file

@ -150,7 +150,10 @@ func (g *Gateway) Close() error {
g.Pacemaker.Stop() g.Pacemaker.Stop()
// Stop the event handler // Stop the event handler
defer close(g.handler) if g.handler != nil {
close(g.handler)
g.handler = nil
}
// Stop the Websocket // Stop the Websocket
return g.WS.Close(nil) return g.WS.Close(nil)
@ -190,7 +193,10 @@ func (g *Gateway) Open() error {
// If the connection is rate limited (documented behavior): // If the connection is rate limited (documented behavior):
// https://discordapp.com/developers/docs/topics/gateway#rate-limiting // https://discordapp.com/developers/docs/topics/gateway#rate-limiting
if err == ErrInvalidSession { if err == ErrInvalidSession {
continue // retry // Close the connection
g.Close()
continue // then retry
} }
// Else, fatal // Else, fatal

View file

@ -32,9 +32,10 @@ func TestIntegration(t *testing.T) {
t.Fatal("Failed to authenticate with Discord:", err) t.Fatal("Failed to authenticate with Discord:", err)
} }
ready, ok := wait(t, gateway.Events).(*ReadyEvent) ev := wait(t, gateway.Events)
ready, ok := ev.(*ReadyEvent)
if !ok { if !ok {
t.Fatal("Event received is not of type Ready:", ready) t.Fatal("Event received is not of type Ready:", ev)
} }
if gateway.SessionID == "" { if gateway.SessionID == "" {
@ -48,18 +49,15 @@ func TestIntegration(t *testing.T) {
t.Fatal("Failed to reconnect:", err) t.Fatal("Failed to reconnect:", err)
} }
/* TODO: this isn't true, as Discord would keep sending Invalid Sessions. /* TODO: We're not testing this, as Discord will replay events before it
* sends the Resumed event.
resumed, ok := (<-gateway.Events).(*ResumedEvent) resumed, ok := (<-gateway.Events).(*ResumedEvent)
if !ok { if !ok {
t.Fatal("Event received is not of type Resumed:", resumed) t.Fatal("Event received is not of type Resumed:", resumed)
} }
*/ */
ready, ok = wait(t, gateway.Events).(*ReadyEvent)
if !ok {
t.Fatal("Event received is not of type Ready:", ready)
}
if err := g.Close(); err != nil { if err := g.Close(); err != nil {
t.Fatal("Failed to close Gateway:", err) t.Fatal("Failed to close Gateway:", err)
} }

View file

@ -2,6 +2,8 @@ package gateway
import ( import (
"fmt" "fmt"
"math/rand"
"time"
"github.com/diamondburned/arikawa/internal/json" "github.com/diamondburned/arikawa/internal/json"
"github.com/diamondburned/arikawa/internal/wsutil" "github.com/diamondburned/arikawa/internal/wsutil"
@ -122,6 +124,9 @@ func HandleOP(g *Gateway, op *OP) error {
return g.Reconnect() return g.Reconnect()
case InvalidSessionOP: case InvalidSessionOP:
// Discord expects us to sleep for no reason
time.Sleep(time.Duration(rand.Intn(5)+1) * time.Second)
// Invalid session, respond with Identify. // Invalid session, respond with Identify.
return g.Identify() return g.Identify()

View file

@ -39,7 +39,10 @@ func (p *Pacemaker) Dead() bool {
} }
func (p *Pacemaker) Stop() { func (p *Pacemaker) Stop() {
if p.stop != nil {
close(p.stop) close(p.stop)
p.stop = nil
}
} }
// Start beats until it's dead. // Start beats until it's dead.
@ -57,10 +60,13 @@ func (p *Pacemaker) start(stop chan struct{}) error {
// Echo at least once // Echo at least once
p.Echo() p.Echo()
// TODO: what happens if the heartbeat fails?
for { for {
select { select {
case <-stop: case <-stop:
return nil return nil
case <-tick.C: case <-tick.C:
if err := p.Pace(); err != nil { if err := p.Pace(); err != nil {
return err return err