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.
Events chan Event
// SessionID is used to store the session ID received after Ready. It is not
// thread-safe.
SessionID string
Identifier *Identifier
Sequence *Sequence
PacerLoop *wsutil.PacemakerLoop
PacerLoop wsutil.PacemakerLoop
ErrorLog func(err error) // default to log.Println
@ -98,11 +101,6 @@ type Gateway struct {
// reconnections or any type of connection interruptions.
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
waitGroup *sync.WaitGroup
}
@ -356,13 +354,11 @@ func (g *Gateway) start(ctx context.Context) 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.
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.
wsutil.WSDebug("Event loop stopped with error:", err)

View File

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

View File

@ -16,7 +16,8 @@ type EventLoopHandler interface {
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 {
pacemaker *heart.Pacemaker // let's not copy this
pacedeath chan error
@ -31,14 +32,6 @@ type PacemakerLoop struct {
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) {
if p.ErrorLog == nil {
WSDebug("Uncaught error:", err)
@ -67,9 +60,15 @@ func (p *PacemakerLoop) Stopped() bool {
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.")
p.pacemaker = heart.NewPacemaker(heartrate, evl.HeartbeatCtx)
p.events = evs
p.handler = evl.HandleOP
// callers should explicitly handle waitgroups.
p.pacedeath = p.pacemaker.StartAsync(nil)
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")
}
// 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.
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.
wsutil.WSDebug("Event loop stopped.")