Start doesnt take context no more. also use NewJob for creating workload
This commit is contained in:
parent
06f1ce010a
commit
15d8f9d5ce
@ -31,10 +31,10 @@ func Example() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Starting up the workers.
|
// Starting up the workers.
|
||||||
d.Start(ctx)
|
d.Start()
|
||||||
|
|
||||||
// Feeding the workers some work.
|
// Feeding the workers some work.
|
||||||
d.Append(work)
|
d.Append(workgroups.NewJob(ctx, work))
|
||||||
|
|
||||||
// Closing the channel for work.
|
// Closing the channel for work.
|
||||||
d.Close()
|
d.Close()
|
||||||
|
@ -11,16 +11,38 @@ import (
|
|||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ErrInWorker is an error that gets returned if there is a error
|
||||||
|
// in the work function.
|
||||||
var ErrInWorker = errors.New("received error in worker")
|
var ErrInWorker = errors.New("received error in worker")
|
||||||
|
|
||||||
type Job func(ctx context.Context) error
|
// Work is a type that defines worker work.
|
||||||
|
type Work func(ctx context.Context) error
|
||||||
|
|
||||||
|
// Job carries a job with everything it needs.
|
||||||
|
// I know know that contexts shouldnt be stored in a struct.
|
||||||
|
// Here is an exception, because its a short living object.
|
||||||
|
// The context is only used as argument for the Work function.
|
||||||
|
// Please use the NewJob function to get around this context in struct shenanigans.
|
||||||
|
type Job struct {
|
||||||
|
ctx context.Context
|
||||||
|
work Work
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewJob creates a new Job to send down the work queue with context and all that stuff.
|
||||||
|
func NewJob(ctx context.Context, work Work) Job {
|
||||||
|
return Job{ctx, work}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dispatcher carries the job queue, the errgroup and the number of workers
|
||||||
|
// to start.
|
||||||
type Dispatcher struct {
|
type Dispatcher struct {
|
||||||
queue chan Job
|
queue chan Job
|
||||||
eg *errgroup.Group
|
eg *errgroup.Group
|
||||||
numWorkers int
|
numWorkers int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewDispatcher creates a new Dispatcher.
|
||||||
|
// It takes a context and adds it to the errgroup creation and returns it again.
|
||||||
func NewDispatcher(ctx context.Context, numWorkers int) (*Dispatcher, context.Context) {
|
func NewDispatcher(ctx context.Context, numWorkers int) (*Dispatcher, context.Context) {
|
||||||
eg, ctx := errgroup.WithContext(ctx)
|
eg, ctx := errgroup.WithContext(ctx)
|
||||||
|
|
||||||
@ -31,7 +53,8 @@ func NewDispatcher(ctx context.Context, numWorkers int) (*Dispatcher, context.Co
|
|||||||
}, ctx
|
}, ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Dispatcher) Start(ctx context.Context) {
|
// Start starts the configured number of workers and waits for jobs.
|
||||||
|
func (d *Dispatcher) Start() {
|
||||||
for i := 0; i < d.numWorkers; i++ {
|
for i := 0; i < d.numWorkers; i++ {
|
||||||
logger := log.With().Caller().Int("worker", i).Logger()
|
logger := log.With().Caller().Int("worker", i).Logger()
|
||||||
logger.Info().Msg("starting worker")
|
logger.Info().Msg("starting worker")
|
||||||
@ -41,12 +64,12 @@ func (d *Dispatcher) Start(ctx context.Context) {
|
|||||||
errChan := make(chan error)
|
errChan := make(chan error)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
errChan <- j(ctx)
|
errChan <- j.work(j.ctx)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-j.ctx.Done():
|
||||||
return fmt.Errorf("got error from context: %w", ctx.Err())
|
return fmt.Errorf("got error from context: %w", j.ctx.Err())
|
||||||
case err := <-errChan:
|
case err := <-errChan:
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("go error from work function: %w", err)
|
return fmt.Errorf("go error from work function: %w", err)
|
||||||
@ -61,7 +84,7 @@ func (d *Dispatcher) Start(ctx context.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append adds a job to the queue.
|
// Append adds a job to the work queue.
|
||||||
func (d *Dispatcher) Append(job Job) {
|
func (d *Dispatcher) Append(job Job) {
|
||||||
log.Debug().Msg("adds job")
|
log.Debug().Msg("adds job")
|
||||||
d.queue <- job
|
d.queue <- job
|
||||||
|
@ -32,10 +32,10 @@ func TestDispatcher(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
d, ctx := workgroups.NewDispatcher(context.Background(), runtime.GOMAXPROCS(0))
|
d, ctx := workgroups.NewDispatcher(context.Background(), runtime.GOMAXPROCS(0))
|
||||||
d.Start(ctx)
|
d.Start()
|
||||||
|
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
d.Append(work)
|
d.Append(workgroups.NewJob(ctx, work))
|
||||||
}
|
}
|
||||||
|
|
||||||
d.Close()
|
d.Close()
|
||||||
@ -53,8 +53,8 @@ func TestDispatcherError(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
d, ctx := workgroups.NewDispatcher(context.Background(), runtime.GOMAXPROCS(0))
|
d, ctx := workgroups.NewDispatcher(context.Background(), runtime.GOMAXPROCS(0))
|
||||||
d.Start(ctx)
|
d.Start()
|
||||||
d.Append(work)
|
d.Append(workgroups.NewJob(ctx, work))
|
||||||
d.Close()
|
d.Close()
|
||||||
err := d.Wait()
|
err := d.Wait()
|
||||||
|
|
||||||
@ -70,12 +70,12 @@ func TestDispatcherTimeout(t *testing.T) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second/2)
|
ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
d, ctx := workgroups.NewDispatcher(ctx, runtime.GOMAXPROCS(0))
|
d, ctx := workgroups.NewDispatcher(ctx, runtime.GOMAXPROCS(0))
|
||||||
d.Start(ctx)
|
d.Start()
|
||||||
d.Append(work)
|
d.Append(workgroups.NewJob(ctx, work))
|
||||||
d.Close()
|
d.Close()
|
||||||
err := d.Wait()
|
err := d.Wait()
|
||||||
require.EqualError(err, "error on waiting: got error from context: context deadline exceeded")
|
require.EqualError(err, "error on waiting: got error from context: context deadline exceeded")
|
||||||
|
Loading…
Reference in New Issue
Block a user