Files
2025-07-17 19:20:27 +00:00

75 lines
1.2 KiB
Go

package controller
import (
"context"
"errors"
"fmt"
"sync"
)
type NotifierService interface {
RunFetchEvents(ctx context.Context) error
}
type Controller struct {
notifier NotifierService
wg sync.WaitGroup
errCh chan error
cancel context.CancelFunc
}
func NewController(notifierService NotifierService) *Controller {
return &Controller{
notifier: notifierService,
wg: sync.WaitGroup{},
errCh: make(chan error, 1),
}
}
// Run service asynchroniously.
func (c *Controller) Run(ctx context.Context) {
ctx, cancel := context.WithCancel(ctx)
c.cancel = cancel
c.wg.Add(1)
go func() {
defer c.wg.Done()
if err := c.notifier.RunFetchEvents(ctx); err != nil && !errors.Is(err, context.Canceled) {
select {
case c.errCh <- fmt.Errorf("RunFetchEvents: %w", err):
default:
}
}
}()
}
// Gracefully stop service.
func (c *Controller) Stop(ctx context.Context) error {
if c.cancel != nil {
c.cancel()
}
done := make(chan struct{})
go func() {
c.wg.Wait()
close(done)
}()
select {
case <-done:
case <-ctx.Done():
return ctx.Err()
}
close(c.errCh)
select {
case err := <-c.errCh:
return err
default:
return nil
}
}