Documentation
¶
Overview ¶
Package task provides some helper to work with common routines so that it can be cancellable or repeatable.
Index ¶
- Variables
- func ContextError(err error) bool
- func ErrorIs(errs ...error) func(error) bool
- func FixedDur(dur time.Duration) func(time.Duration) time.Duration
- type CtxMod
- type ErrOthers
- type Task
- func Copy(dst io.Writer, src io.ReadCloser) Task
- func CopyBuffer(dst io.Writer, src io.ReadCloser, buf []byte) Task
- func First(tasks ...Task) Task
- func FromServer(start func() error, stop func()) Task
- func Iter(tasks ...Task) Task
- func NoCtx(f func() error) Task
- func NoErr(f func()) Task
- func Skip(tasks ...Task) Task
- func Sleep(timeout time.Duration) Task
- func Wait(tasks ...Task) Task
- func (t Task) AlterError(f func(error) error) Task
- func (t Task) Cached() Task
- func (t Task) Defer(f func()) Task
- func (t Task) Exec() error
- func (t Task) Go(ctx context.Context) <-chan error
- func (t Task) GoWithChan(ctx context.Context, ch chan<- error)
- func (t Task) HandleErr(f func(error) error) Task
- func (t Task) HandleErrWithContext(f func(context.Context, error) error) Task
- func (t Task) IgnoreErr() Task
- func (t Task) IgnoreErrs(f func(error) bool) Task
- func (t Task) Loop() Task
- func (t Task) NoCtx() func() error
- func (t Task) NoErr() func()
- func (t Task) Once() Task
- func (t Task) OnlyErrs(f func(error) bool) Task
- func (t Task) Post(f func(error)) Task
- func (t Task) Pre(f func()) Task
- func (t Task) Retry() Task
- func (t Task) RetryIf(errf func(error) bool) Task
- func (t Task) RetryN(n int) Task
- func (t Task) RetryNIf(errf func(error) bool, n int) Task
- func (t Task) Run(ctx context.Context) error
- func (t Task) Then(next Task) Task
- func (t Task) Timed(dur time.Duration) Task
- func (t Task) TimedDone(dur time.Duration) Task
- func (t Task) TimedDoneF(f func(time.Duration) time.Duration) Task
- func (t Task) TimedF(f func(time.Duration) time.Duration) Task
- func (t Task) TimedFail(dur time.Duration) Task
- func (t Task) TimedFailF(f func(time.Duration) time.Duration) Task
- func (t Task) With(modder CtxMod) Task
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrOnce = errors.New("the task can only be executed once.")
var ErrOneHasDone = errors.New("another task has been done")
Functions ¶
func ContextError ¶ added in v0.3.0
ContextError detects if err is context.Canceled or context.DeadlineExceeded.
Types ¶
type ErrOthers ¶ added in v0.2.3
type ErrOthers struct {
// contains filtered or unexported fields
}
type Task ¶
Task repeasents a (maybe) cancellable routine.
func Copy ¶
func Copy(dst io.Writer, src io.ReadCloser) Task
Copy wraps io.Copy into a cancellable task. Cancelling context will close src.
func CopyBuffer ¶ added in v0.1.0
Copy wraps io.CopyBuffer into a cancellable task. Cancelling context will close src.
func First ¶ added in v0.1.0
First creates a task that runs tasks concurrently, return first result and cancel others. Other tasks receives ErrOneHasDone as cancel cause.
Take care of NoCtx and NoErr tasks as it cannot be cancelled by context.
func FromServer ¶
FromServer creates a task from something can be started or stopped. Running the task calls start, and cancelling context calls stop.
func Iter ¶
Iter creates a task run tasks with same context and stops at first error.
Example ¶
e := errors.New("err")
a := func(_ context.Context) error { fmt.Println("a"); return nil }
b := func(_ context.Context) error { fmt.Println("b"); return e }
c := func(_ context.Context) error { fmt.Println("c"); return nil }
err := Iter(a, b, c).Run(context.Background())
if err != e {
fmt.Println("unexpected error:", err)
return
}
Output: a b
func NoErr ¶ added in v0.3.0
func NoErr(f func()) Task
NoErr wraps a never-fail, non-cancellable function into task.
func Skip ¶
Skip creates a task that runs tasks concurrently, cancel others if any error, and wait them done.
Tasks canceled by this receieves ErrOthers which wraps the error as cancel cause.
Take care of NoCtx and NoErr tasks as it cannot be cancelled by context.
Example ¶
e := errors.New("err")
a := func(ctx context.Context) error {
if err := Sleep(time.Minute).Run(ctx); err != nil {
fmt.Println("context canceled")
return err
}
fmt.Println("a")
return nil
}
b := func(_ context.Context) error { fmt.Println("b"); return e }
c := func(ctx context.Context) error {
if err := Sleep(time.Minute).Run(ctx); err != nil {
fmt.Println("context canceled")
return err
}
fmt.Println("c")
return nil
}
err := Skip(a, b, c).Run(context.Background())
if err != e {
fmt.Println("unexpected error:", err)
return
}
Output: b context canceled context canceled
func Wait ¶
Wait creates a task that runs all task concurrently, wait them get done, and return first non-nil error.
func (Task) AlterError ¶ added in v0.3.0
AlterError wraps t to run f to alter the error before returning.
func (Task) Cached ¶ added in v0.3.0
Cached wraps t to cache the result, and reuse it in later call.
Example ¶
t := NoCtx(func() error {
fmt.Println("executed")
return errors.New("error")
})
ctx := context.TODO()
fmt.Println(t.Run(ctx)) // error
cached := t.Cached()
fmt.Println(cached.Run(ctx)) // error
fmt.Println(cached.Run(ctx)) // error
Output: executed error executed error error
func (Task) Exec ¶ added in v0.1.0
Exec runs the task with empty context (context.Background).
func (Task) Go ¶ added in v0.1.0
Go runs t in separated goroutine and returns a channel to retrieve error.
It's safe to ignore the channel if you don't need the result.
func (Task) GoWithChan ¶ added in v0.1.0
GoWithChan runs t in separated goroutine and sends returned error into ch.
func (Task) HandleErr ¶ added in v0.1.0
HandleErr creates a task that handles specific error after running t. It could change the error returned by Run. f is called only if t.Run returns an error.
func (Task) HandleErrWithContext ¶ added in v0.1.0
HandleErrWithContext is like HandleErr, but uses same context used in f.
func (Task) IgnoreErr ¶ added in v0.1.0
IgnoreErr ignores the error returned by t.Run if it is not context error.
It is shortcut to t.OnlyErrs(ContextError).
func (Task) IgnoreErrs ¶ added in v0.1.0
IgnoreErrs ignores errors if f(error) is true.
func (Task) Loop ¶ added in v0.1.0
Loop creates a task that repeatedly runs t with same context until it returns an error.
func (Task) NoCtx ¶ added in v0.3.0
NoCtx converts the task into a simple function by feeding empty context when run.
func (Task) NoErr ¶ added in v0.3.0
func (t Task) NoErr() func()
NoErr converts the task into a simple function by feeding empty context when run.
func (Task) Once ¶ added in v0.1.0
Once creates a task that can be run only once, further attempt returns ErrOnce.
Example ¶
t := NoCtx(func() error {
fmt.Println("executed")
return errors.New("error")
})
ctx := context.TODO()
fmt.Println(t.Run(ctx)) // error
once := t.Once()
fmt.Println(once.Run(ctx)) // error
fmt.Println(errors.Is(once.Run(ctx), ErrOnce)) // ErrOnce
Output: executed error executed error true
func (Task) Retry ¶ added in v0.1.0
Retry creates a task thats repeatedly runs t with same context until it returns nil.
Retrying [Micro] task is resource-wasting as it never fail.
func (Task) RetryIf ¶ added in v0.3.1
RetryIf is like Retry, but retries only if errf returns true.
Error passed to errf can never be nil.
func (Task) RetryN ¶ added in v0.1.0
RetryN is like Retry, but retries no more than n times.
In other words, RetryN(2) will run at most 3 times:
- first try
- first retry
- second retry
Retrying [Micro] task is resource-wasting as it never fail.
Example ¶
ctx := context.Background()
n := 1
errTask := func(_ context.Context) error {
fmt.Println(n)
n++
return errors.New("")
}
retry := Task(errTask).RetryN(2)
retry.Run(ctx)
Output: 1 2 3
func (Task) RetryNIf ¶ added in v0.3.1
RetryNIf is like RetryN, but retries only if errf returns true.
Error passed to errf can never be nil.
func (Task) Then ¶ added in v0.3.0
Next creates a task that runs next after t finished successfully.
func (Task) Timed ¶ added in v0.1.0
Timed wraps t into a task ensures that it is not returned before dur passed.
It focuses on "How long I should wait before returning". Take a look at example for how it works.
If you're looking for rate limiting solution, you should take a look at "rated" subdirectory.
Example ¶
ctx := context.Background()
begin := time.Now()
quickTask := Task(func(_ context.Context) error {
// simulates a quick task like computing 1+1
fmt.Printf("quick done at +%d socond\n", time.Since(begin)/time.Second)
return nil
}).Timed(time.Second)
quickTask.Run(ctx)
fmt.Printf("quick returns at +%d second\n", time.Since(begin)/time.Second)
begin = time.Now()
slowTask := Task(func(_ context.Context) error {
// simulates a slow task like calling web api
time.Sleep(2 * time.Second)
fmt.Printf("slow done at +%d socond\n", time.Since(begin)/time.Second)
return nil
}).Timed(time.Second)
slowTask.Run(ctx)
fmt.Printf("slow returns at +%d second\n", time.Since(begin)/time.Second)
Output: quick done at +0 socond quick returns at +1 second slow done at +2 socond slow returns at +2 second
func (Task) TimedDone ¶ added in v0.1.0
TimedDone is like Timed, but limits only successful run.
If you're looking for rate limiting solution, you should take a look at "rated" subdirectory.
Example ¶
ctx := context.Background()
begin := time.Now()
doneTask := Task(func(_ context.Context) error {
// a task which always success
return nil
}).TimedDone(time.Second)
doneTask.Run(ctx)
fmt.Printf("done returns at +%d second\n", time.Since(begin)/time.Second)
begin = time.Now()
failTask := Task(func(_ context.Context) error {
return errors.New("a task which always fail")
}).TimedDone(time.Second)
failTask.Run(ctx)
fmt.Printf("fail returns at +%d second\n", time.Since(begin)/time.Second)
Output: done returns at +1 second fail returns at +0 second
func (Task) TimedDoneF ¶ added in v0.1.0
TimedDoneF is like TimedDone, but use function instead.
The function accepts actual execution time, and returns how long it should wait.
func (Task) TimedF ¶ added in v0.1.0
TimedF is like Timed, but use function instead.
The function accepts actual execution time, and returns how long it should wait.
func (Task) TimedFail ¶ added in v0.1.0
TimedFail is like Timed, but limits only failed run.
If you're looking for rate limiting solution, you should take a look at "rated" subdirectory.
func (Task) TimedFailF ¶ added in v0.1.0
TimedFailF is like TimedFail, but use function instead.
The function accepts actual execution time, and returns how long it should wait.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package action is designed to write code like this:
|
Package action is designed to write code like this: |
|
Package deptask provides a tool, Runner, to run tasks in order according to its dependency.
|
Package deptask provides a tool, Runner, to run tasks in order according to its dependency. |
|
Package httptask provides some helper to wrap http server and some client job into task.
|
Package httptask provides some helper to wrap http server and some client job into task. |
|
Package lossy contains wait/notify and pub/sub implementations that can lose data.
|
Package lossy contains wait/notify and pub/sub implementations that can lose data. |
|
noctx
|
|
|
ncaction
Package ncaction is basically action package without context.Context support.
|
Package ncaction is basically action package without context.Context support. |
|
ncrated
Package ncrated is [rated] package for nctask and ncaction.
|
Package ncrated is [rated] package for nctask and ncaction. |
|
nctask
Package nctask provides most helpers in task package for "func() error" type
|
Package nctask provides most helpers in task package for "func() error" type |
|
Package rated controls rate of a task with rate.Limiter.
|
Package rated controls rate of a task with rate.Limiter. |