Description
sync/workerpool
This package would provide a standardized concurrent worker pool implementation with a simple task interface.
package workerpool
type Task interface {
Invoke(ctx context.Context) error
}
type WorkerPool struct {}
func New(n int64) WorkerPool
func (p *WorkerPool) Push(t Task, opts ...TaskOption)
func (p *WorkerPool) Run(ctx context.Context)
func (p WorkerPool) Wait()
Example
package main
import (
"context"
"golang.org/x/sync/workerpool"
)
func main() {
wp := workerpool.New(2)
ctx, cancel := context.WithCancel(context.Background())
go wp.Run(ctx) // runs until context is cancelled
// wp.Push(Task 1)
// wp.Push(Task 2)
wp.Wait() // blocks until all pending tasks are complete, but does not stop workerpool goroutine
cancel() // stops the workerpool
// wait for the workerpool to be stopped
select {
case <-ctx.Done():
}
}
Reasoning
While there are many overly simplistic examples published on the internet, the problem space gains difficulty quickly when trying to write a more robust custom implementation. I believe the community would benefit greatly by having such a robust implementation widely available in the standard library.
I've written github.com/tniswong/workerpool as a draft design that I offer up as a candidate implementation. This design uses golang.org/x/sync/semaphore
for bounding the concurrent workers.
Design Notes
- Uses
context.Context
for bothWorkerPool.Run(context.Context)
andTask.Invoke(context.Context)
- The task queue has no code-defined size limitations
- Tasks are responsible for collecting their own results upon completion (if applicable)
Push()
is concurrency safePush()
can be supplied options to specify task invocation behavior such as Retry (restart the task if it returned an error) and RetryMax (restart the task unless it returns an error more than n times)Does not invoke queued tasks when context is cancelledWhen Run(ctxt) is ctxt cancelled, remaining jobs are invoked with the cancelled context to clear out the work queue.- No hanging worker threads to clean up thanks to the semaphore
Run()
runs until the context is cancelled
References
https://brandur.org/go-worker-pool
https://gobyexample.com/worker-pools
https://itnext.io/explain-to-me-go-concurrency-worker-pool-pattern-like-im-five-e5f1be71e2b0
https://medium.com/code-chasm/go-concurrency-pattern-worker-pool-a437117025b1
https://golangbot.com/buffered-channels-worker-pools/
https://github.com/gammazero/workerpool
https://github.com/alitto/pond
https://github.com/cilium/workerpool
https://github.com/vardius/worker-pool
Metadata
Metadata
Assignees
Type
Projects
Status