workgate

package
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 10, 2023 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package workgate provides a struct to ensure no more than N tasks are ever ongoing.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrGateClosed is returned from WorkGate.{Try,}Do() if the gate has been closed.
	ErrGateClosed = errors.New("gate closed")
	// ErrGateFull is returned from WorkGate.TryDo if the gate is full.
	ErrGateFull = errors.New("gate full")
)

Functions

This section is empty.

Types

type WorkGate

type WorkGate struct {
	// contains filtered or unexported fields
}

WorkGate can ensure a maximum of N concurrent tasks are ever ongoing. It does _not_ wait for any tasks, use an additional WaitGroup for that.

func New

func New(maxWorkers uint) *WorkGate

New creates a new WorkGate.

func (*WorkGate) Close

func (wg *WorkGate) Close()

Close prevents further work from being done and the state is permanent. Can be called multiple times.

func (*WorkGate) Do

func (wg *WorkGate) Do(task func() (interface{}, error)) (interface{}, error)

Do a task on the calling thread. Returns the return value of task. Task is silently dropped if gate has been closed.

Example
wg := New(10)
returnValue, err := wg.Do(func() (interface{}, error) {
	// Do some work (blocking)
	return "foo", nil
})
if err != nil {
	panic(err)
}
fmt.Println(returnValue)
Output:

foo

func (*WorkGate) DoAsync

func (wg *WorkGate) DoAsync(task func(), errorHandler func(error)) error

DoAsync executes the task in a goroutine. Note that it will block if all slots are currently occupied If the gate is closed it returns ErrGateClosed If the task panics the errorHandler fuction will be called with the recovered panic. If errorHandler is nil panics won't be recovered.

Example
wg := New(10)
done := make(chan struct{})
wg.DoAsync(
	func() {
		// Do some work (async)
		fmt.Println("foo")
		close(done)
	},
	func(err error) {
		fmt.Println(err)
		close(done)
	},
)
<-done
Output:

foo

func (*WorkGate) DoAsyncContext

func (wg *WorkGate) DoAsyncContext(ctx context.Context, task func(), errorHandler func(error))

DoAsyncContext is like DoAsync but accepts a context if that is cancelled it will stop waiting and the errorHandler fuction will be called with ctx.Err() If the gate is closed the errorHandler fuction will be called with ErrGateClosed If the task panics the errorHandler fuction will be called with the recovered panic. If errorHandler is nil panics won't be recovered.

func (*WorkGate) Enter

func (wg *WorkGate) Enter() (res bool)

Enter grabs a token from the WorkGate. If this function returns true the caller is free to do work. If it returns false the gate has been closed. Caller MUST call wg.Leave() when done (AND Enter() returned true). Low level API, not normally used.

func (*WorkGate) Leave

func (wg *WorkGate) Leave()

Leave must be called when work has been completed after a call to Enter(). Low level API, not normally used.

func (*WorkGate) MaxWorkers

func (wg *WorkGate) MaxWorkers() int

MaxWorkers returns the maximum number of concurrent tasks.

func (*WorkGate) TryDo

func (wg *WorkGate) TryDo(task func() (interface{}, error)) (res interface{}, err error)

TryDo is like Do, but returns an error if the gate is full.

Example
wg := New(10)

// Make sure the gate is full
free := make(chan struct{})
for i := 0; i < 10; i++ {
	wg.DoAsync(
		func() {
			<-free
		},
		nil,
	)
}
defer close(free)

_, err := wg.TryDo(func() (interface{}, error) {
	// Do some work (blocking)
	return "foo", nil
})
fmt.Println(err)
Output:

gate full

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL