session: Add Gateway{IsAlive,Error} methods

This commit adds the above 2 methods mostly for the user's convenience.

GatewayIsAlive will be useful when handling CloseError events and
determining if the session was fatal without needing to handle Open().

GatewayError builds upon GatewayIsAlive and returns an error. While the
user could call GatewayIsAlive and LastError themselves, doing so
without locking is technically racy if another thread wants to
reconnect.
This commit is contained in:
diamondburned 2022-04-07 23:27:34 -07:00
parent 34db90a16d
commit 723aa0e4c3
No known key found for this signature in database
GPG Key ID: D78C4471CE776659
1 changed files with 45 additions and 3 deletions

View File

@ -142,9 +142,51 @@ func (s *Session) HasIntents(intents gateway.Intents) bool {
// or Session was never constructed with a gateway, then nil is returned.
func (s *Session) Gateway() *gateway.Gateway {
s.state.Lock()
g := s.state.gateway
s.state.Unlock()
return g
defer s.state.Unlock()
return s.state.gateway
}
// GatewayError returns the gateway's error if the gateway is dead. If it's not
// dead, then nil is always returned. The check is done with GatewayIsAlive().
// If the gateway has never been started, nil will be returned (even though
// GatewayIsAlive would've returned true).
//
// This method would return what Close() would've returned if a fatal gateway
// error was found.
func (s *Session) GatewayError() error {
s.state.Lock()
defer s.state.Unlock()
if !s.gatewayIsAlive() && s.state.gateway != nil {
return s.state.gateway.LastError()
}
return nil
}
// GatewayIsAlive returns true if the gateway is still alive, that is, it is
// either connected or is trying to reconnect after an interruption. In other
// words, false is returned if the gateway isn't open or it has exited after
// seeing a fatal error code (and therefore cannot recover).
func (s *Session) GatewayIsAlive() bool {
s.state.Lock()
defer s.state.Unlock()
return s.gatewayIsAlive()
}
func (s *Session) gatewayIsAlive() bool {
if s.state.gateway == nil || s.state.doneCh == nil {
return false
}
select {
case <-s.state.doneCh:
return false
default:
return true
}
}
// Open opens the Discord gateway and its handler, then waits until either the