1
0
Fork 0
mirror of https://github.com/diamondburned/arikawa.git synced 2024-11-30 18:53:30 +00:00

Session: Added an AfterClose handler as a *session.Close event

This commit is contained in:
diamondburned (Forefront) 2020-04-06 19:36:06 -07:00
parent 5750876348
commit 2f597ebc0b
3 changed files with 33 additions and 1 deletions

View file

@ -85,6 +85,11 @@ type Gateway struct {
ErrorLog func(err error) // default to log.Println ErrorLog func(err error) // default to log.Println
// AfterClose is called after each close. Error can be non-nil, as this is
// called even when the Gateway is gracefully closed. It's used mainly for
// reconnections or any type of connection interruptions.
AfterClose func(err error) // noop by default
// FatalError is where Reconnect errors will go to. When an error is sent // FatalError is where Reconnect errors will go to. When an error is sent
// here, the Gateway is already dead, so Close() shouldn't be called. // here, the Gateway is already dead, so Close() shouldn't be called.
// This channel is buffered once. // This channel is buffered once.
@ -127,6 +132,7 @@ func NewGatewayWithDriver(token string, driver json.Driver) (*Gateway, error) {
Identifier: DefaultIdentifier(token), Identifier: DefaultIdentifier(token),
Sequence: NewSequence(), Sequence: NewSequence(),
ErrorLog: WSError, ErrorLog: WSError,
AfterClose: func(error) {},
fatalError: make(chan error, 1), fatalError: make(chan error, 1),
} }
g.FatalError = g.fatalError g.FatalError = g.fatalError
@ -152,6 +158,8 @@ func (g *Gateway) Close() error {
// Check if the WS is already closed: // Check if the WS is already closed:
if g.waitGroup == nil && g.paceDeath == nil { if g.waitGroup == nil && g.paceDeath == nil {
WSDebug("Gateway is already closed.") WSDebug("Gateway is already closed.")
g.AfterClose(nil)
return nil return nil
} }
@ -177,7 +185,9 @@ func (g *Gateway) Close() error {
g.waitGroup = nil g.waitGroup = nil
// Stop the Websocket // Stop the Websocket
return g.WS.Close() err := g.WS.Close()
g.AfterClose(err)
return err
} }
// Reconnects and resumes. // Reconnects and resumes.

View file

@ -52,6 +52,9 @@ func TestIntegration(t *testing.T) {
if err != nil { if err != nil {
t.Fatal("Failed to make a Gateway:", err) t.Fatal("Failed to make a Gateway:", err)
} }
g.AfterClose = func(err error) {
log.Println("Closed.")
}
gateway = g gateway = g
if err := g.Open(); err != nil { if err := g.Open(); err != nil {

View file

@ -13,6 +13,18 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
) )
// Closed is an event that's sent to Session's command handler. This works by
// using (*Gateway).AfterError. If the user sets this callback, no Closed events
// would be sent.
//
// Usage
//
// ses.AddHandler(func(*session.Closed) {})
//
type Closed struct {
Error error
}
var ErrMFA = errors.New("Account has 2FA enabled") var ErrMFA = errors.New("Account has 2FA enabled")
// Session manages both the API and Gateway. As such, Session inherits all of // Session manages both the API and Gateway. As such, Session inherits all of
@ -92,6 +104,13 @@ func (s *Session) Open() error {
s.hstop = stop s.hstop = stop
go s.startHandler(stop) go s.startHandler(stop)
// Set the AfterClose's handler.
s.Gateway.AfterClose = func(err error) {
s.Handler.Call(&Closed{
Error: err,
})
}
if err := s.Gateway.Open(); err != nil { if err := s.Gateway.Open(); err != nil {
return errors.Wrap(err, "Failed to start gateway") return errors.Wrap(err, "Failed to start gateway")
} }