in pkg/sync/pool/worker.go [70:113]
func Work(worker Worker) {
var timedout bool
defer func() { worker.Stopped <- timedout }()
var done = make(chan struct{})
for {
select {
case task := <-worker.Queue:
// This is necessary to allow the work to happen in the background
// and still react to any sent to worker.stop and be able to clean
// shutdown the worker even if the work is in flight.
go func(w Validator, d chan<- struct{}) {
if err := worker.Run(w); err != nil {
worker.Errors <- err
}
d <- struct{}{}
}(task, done)
select {
// Receives the done signal when the work is done.
case <-done:
worker.Finished <- struct{}{}
// Handles the case where the worker is processing a work item and
// and a stop signal is received while the work is in flight.
case <-worker.Stop:
// This gives one last chance to the worker to complete the
// work before returning with a timeout and sending the item
// to the leftover queue.
select {
case <-done:
worker.Finished <- struct{}{}
case <-time.After(worker.StopTimeout):
worker.Leftovers <- task
timedout = true
}
return
}
// Handle case where the worker is idle and the stop signal is received
case <-worker.Stop:
return
}
}
}