package main import ( "context" "log" ) type Task func() error type Queue struct { ch chan Task done chan struct{} } func NewQueue(buf int) *Queue { return &Queue{ch: make(chan Task, buf)} } func (q *Queue) Push(t Task) { q.ch <- t } func (q *Queue) Run(ctx context.Context) { q.done = make(chan struct{}) go func() { defer close(q.done) for { select { case t := <-q.ch: if err := t(); err != nil { log.Printf("task failed: %v", err) } case <-ctx.Done(): return } } }() } func (q *Queue) Stop() { close(q.ch) <-q.done }