Documentation
¶
Overview ¶
Package workgate provides a struct to ensure no more than N tasks are ever ongoing.
Index ¶
- Variables
- type WorkGate
- func (wg *WorkGate) Close()
- func (wg *WorkGate) Do(task func() (interface{}, error)) (interface{}, error)
- func (wg *WorkGate) DoAsync(task func(), errorHandler func(error)) error
- func (wg *WorkGate) DoAsyncContext(ctx context.Context, task func(), errorHandler func(error))
- func (wg *WorkGate) Enter() (res bool)
- func (wg *WorkGate) Leave()
- func (wg *WorkGate) MaxWorkers() int
- func (wg *WorkGate) TryDo(task func() (interface{}, error)) (res interface{}, err error)
Examples ¶
Constants ¶
This section is empty.
Variables ¶
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 (*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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
MaxWorkers returns the maximum number of concurrent tasks.
func (*WorkGate) TryDo ¶
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