1
0
Fork 0
mirror of https://github.com/diamondburned/arikawa.git synced 2024-11-27 17:23:00 +00:00

wsutil: Made PacemakerLoop valid as zero-value

This commit is contained in:
diamondburned 2020-08-19 20:48:55 -07:00 committed by diamondburned
parent f0c73f4c99
commit de61fd912d
4 changed files with 16 additions and 25 deletions

View file

@ -85,11 +85,14 @@ type Gateway struct {
// Session. // Session.
Events chan Event Events chan Event
// SessionID is used to store the session ID received after Ready. It is not
// thread-safe.
SessionID string SessionID string
Identifier *Identifier Identifier *Identifier
Sequence *Sequence Sequence *Sequence
PacerLoop *wsutil.PacemakerLoop
PacerLoop wsutil.PacemakerLoop
ErrorLog func(err error) // default to log.Println ErrorLog func(err error) // default to log.Println
@ -98,11 +101,6 @@ type Gateway struct {
// reconnections or any type of connection interruptions. // reconnections or any type of connection interruptions.
AfterClose func(err error) // noop by default AfterClose func(err error) // noop by default
// Mutex to hold off calls when the WS is not available. Doesn't block if
// Start() is not called or Close() is called. Also doesn't block for
// Identify or Resume.
// available sync.RWMutex
// Filled by methods, internal use // Filled by methods, internal use
waitGroup *sync.WaitGroup waitGroup *sync.WaitGroup
} }
@ -356,13 +354,11 @@ func (g *Gateway) start(ctx context.Context) error {
return errors.Wrap(err, "first error") return errors.Wrap(err, "first error")
} }
// Use the pacemaker loop.
g.PacerLoop = wsutil.NewLoop(hello.HeartbeatInterval.Duration(), ch, g)
// Start the event handler, which also handles the pacemaker death signal. // Start the event handler, which also handles the pacemaker death signal.
g.waitGroup.Add(1) g.waitGroup.Add(1)
g.PacerLoop.RunAsync(func(err error) { // Use the pacemaker loop.
g.PacerLoop.RunAsync(hello.HeartbeatInterval.Duration(), ch, g, func(err error) {
g.waitGroup.Done() // mark so Close() can exit. g.waitGroup.Done() // mark so Close() can exit.
wsutil.WSDebug("Event loop stopped with error:", err) wsutil.WSDebug("Event loop stopped with error:", err)

View file

@ -71,7 +71,6 @@ func (g *Gateway) HandleOP(op *wsutil.OP) error {
return nil return nil
case HelloOP: case HelloOP:
// What is this OP doing here???
return nil return nil
case DispatchOP: case DispatchOP:

View file

@ -16,7 +16,8 @@ type EventLoopHandler interface {
HeartbeatCtx(context.Context) error HeartbeatCtx(context.Context) error
} }
// PacemakerLoop provides an event loop with a pacemaker. // PacemakerLoop provides an event loop with a pacemaker. A zero-value instance
// is a valid instance only when RunAsync is called first.
type PacemakerLoop struct { type PacemakerLoop struct {
pacemaker *heart.Pacemaker // let's not copy this pacemaker *heart.Pacemaker // let's not copy this
pacedeath chan error pacedeath chan error
@ -31,14 +32,6 @@ type PacemakerLoop struct {
ErrorLog func(error) ErrorLog func(error)
} }
func NewLoop(heartrate time.Duration, evs <-chan Event, evl EventLoopHandler) *PacemakerLoop {
return &PacemakerLoop{
pacemaker: heart.NewPacemaker(heartrate, evl.HeartbeatCtx),
events: evs,
handler: evl.HandleOP,
}
}
func (p *PacemakerLoop) errorLog(err error) { func (p *PacemakerLoop) errorLog(err error) {
if p.ErrorLog == nil { if p.ErrorLog == nil {
WSDebug("Uncaught error:", err) WSDebug("Uncaught error:", err)
@ -67,9 +60,15 @@ func (p *PacemakerLoop) Stopped() bool {
return p == nil || !p.running.Get() return p == nil || !p.running.Get()
} }
func (p *PacemakerLoop) RunAsync(exit func(error)) { func (p *PacemakerLoop) RunAsync(
heartrate time.Duration, evs <-chan Event, evl EventLoopHandler, exit func(error)) {
WSDebug("Starting the pacemaker loop.") WSDebug("Starting the pacemaker loop.")
p.pacemaker = heart.NewPacemaker(heartrate, evl.HeartbeatCtx)
p.events = evs
p.handler = evl.HandleOP
// callers should explicitly handle waitgroups. // callers should explicitly handle waitgroups.
p.pacedeath = p.pacemaker.StartAsync(nil) p.pacedeath = p.pacemaker.StartAsync(nil)
p.running.Set(true) p.running.Set(true)

View file

@ -181,13 +181,10 @@ func (c *Gateway) __start(ctx context.Context) error {
return errors.Wrap(err, "failed to wait for Ready or Resumed") return errors.Wrap(err, "failed to wait for Ready or Resumed")
} }
// Create an event loop executor.
c.EventLoop = wsutil.NewLoop(hello.HeartbeatInterval.Duration(), ch, c)
// Start the event handler, which also handles the pacemaker death signal. // Start the event handler, which also handles the pacemaker death signal.
c.waitGroup.Add(1) c.waitGroup.Add(1)
c.EventLoop.RunAsync(func(err error) { c.EventLoop.RunAsync(hello.HeartbeatInterval.Duration(), ch, c, func(err error) {
c.waitGroup.Done() // mark so Close() can exit. c.waitGroup.Done() // mark so Close() can exit.
wsutil.WSDebug("Event loop stopped.") wsutil.WSDebug("Event loop stopped.")