package workers import ( "context" "fmt" "time" ) type Worker struct { period time.Duration errChan chan error } // New creation of worker func New(p time.Duration) *Worker { return &Worker{ period: p, errChan: make(chan error), } } // Start method for starting worker with long polling from postgres func (t *Worker) Start(ctx context.Context, job func(ctx context.Context) error) { metronome := time.Tick(t.period) for { select { case <-metronome: func() { defer func() { if v := recover(); v != any(nil) { t.errChan <- fmt.Errorf("%v", v) } }() if err := job(ctx); err != nil { t.errChan <- err } }() case <-ctx.Done(): return } } } func (t *Worker) ExposeErr(ctx context.Context, err *error) { go func() { for { select { case e := <-t.errChan: err = &e case <-ctx.Done(): return } } }() }