task

package module
v0.3.5 Latest Latest
Warning

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

Go to latest
Published: Sep 27, 2025 License: MPL-2.0 Imports: 5 Imported by: 4

Documentation

Overview

Package task provides some helper to work with common routines so that it can be cancellable or repeatable.

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrOnce = errors.New("the task can only be executed once.")
View Source
var ErrOneHasDone = errors.New("another task has been done")

Functions

func ContextError added in v0.3.0

func ContextError(err error) bool

ContextError detects if err is context.Canceled or context.DeadlineExceeded.

func ErrorIs added in v0.3.0

func ErrorIs(errs ...error) func(error) bool

ErrorIs creates a function to detect if the error is listed.

func FixedDur added in v0.3.0

func FixedDur(dur time.Duration) func(time.Duration) time.Duration

FixedDur creats a func to be used in TimedF, TimedDoneF and TimedFailF, which does not take actual execution time into consideration.

Types

type CtxMod

type CtxMod func(context.Context) (context.Context, func())

CtxMod defines how you modify a context.

func Timeout added in v0.1.0

func Timeout(dur time.Duration) CtxMod

Timeout creates a CtxMod which adds timeout info to a context.

type ErrOthers added in v0.2.3

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

func (ErrOthers) As added in v0.2.3

func (e ErrOthers) As(v interface{}) bool

func (ErrOthers) Error added in v0.2.3

func (e ErrOthers) Error() string

func (ErrOthers) Is added in v0.2.3

func (e ErrOthers) Is(err error) bool

func (ErrOthers) Unwrap added in v0.2.3

func (e ErrOthers) Unwrap() error

type Task

type Task func(context.Context) error

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

func CopyBuffer(dst io.Writer, src io.ReadCloser, buf []byte) Task

Copy wraps io.CopyBuffer into a cancellable task. Cancelling context will close src.

func First added in v0.1.0

func First(tasks ...Task) Task

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

func FromServer(start func() error, stop func()) Task

FromServer creates a task from something can be started or stopped. Running the task calls start, and cancelling context calls stop.

func Iter

func Iter(tasks ...Task) Task

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 NoCtx added in v0.3.0

func NoCtx(f func() error) Task

NoCtx wraps a non-cancellable function into task.

func NoErr added in v0.3.0

func NoErr(f func()) Task

NoErr wraps a never-fail, non-cancellable function into task.

func Skip

func Skip(tasks ...Task) Task

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 Sleep

func Sleep(timeout time.Duration) Task

Sleep is a cancellable time.Sleep in task form.

func Wait

func Wait(tasks ...Task) Task

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

func (t Task) AlterError(f func(error) error) Task

AlterError wraps t to run f to alter the error before returning.

func (Task) Cached added in v0.3.0

func (t Task) Cached() Task

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) Defer added in v0.2.4

func (t Task) Defer(f func()) Task

Defer wraps t to run f after it.

func (Task) Exec added in v0.1.0

func (t Task) Exec() error

Exec runs the task with empty context (context.Background).

func (Task) Go added in v0.1.0

func (t Task) Go(ctx context.Context) <-chan error

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

func (t Task) GoWithChan(ctx context.Context, ch chan<- error)

GoWithChan runs t in separated goroutine and sends returned error into ch.

func (Task) HandleErr added in v0.1.0

func (t Task) HandleErr(f func(error) error) Task

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

func (t Task) HandleErrWithContext(f func(context.Context, error) error) Task

HandleErrWithContext is like HandleErr, but uses same context used in f.

func (Task) IgnoreErr added in v0.1.0

func (t Task) IgnoreErr() Task

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

func (t Task) IgnoreErrs(f func(error) bool) Task

IgnoreErrs ignores errors if f(error) is true.

func (Task) Loop added in v0.1.0

func (t Task) Loop() Task

Loop creates a task that repeatedly runs t with same context until it returns an error.

func (Task) NoCtx added in v0.3.0

func (t Task) NoCtx() func() error

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

func (t Task) Once() Task

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) OnlyErrs added in v0.1.0

func (t Task) OnlyErrs(f func(error) bool) Task

OnlyErrs preserves errors if f(error) is true.

func (Task) Post added in v0.2.4

func (t Task) Post(f func(error)) Task

Post wraps t to run f after it.

func (Task) Pre added in v0.2.4

func (t Task) Pre(f func()) Task

Pre wraps t to run f before it.

func (Task) Retry added in v0.1.0

func (t Task) Retry() Task

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

func (t Task) RetryIf(errf func(error) bool) Task

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

func (t Task) RetryN(n int) Task

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

func (t Task) RetryNIf(errf func(error) bool, n int) Task

RetryNIf is like RetryN, but retries only if errf returns true.

Error passed to errf can never be nil.

func (Task) Run

func (t Task) Run(ctx context.Context) error

Run runs the task, equals to t(ctx).

func (Task) Then added in v0.3.0

func (t Task) Then(next Task) Task

Next creates a task that runs next after t finished successfully.

func (Task) Timed added in v0.1.0

func (t Task) Timed(dur time.Duration) Task

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

func (t Task) TimedDone(dur time.Duration) Task

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

func (t Task) TimedDoneF(f func(time.Duration) time.Duration) Task

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

func (t Task) TimedF(f func(time.Duration) time.Duration) Task

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

func (t Task) TimedFail(dur time.Duration) Task

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

func (t Task) TimedFailF(f func(time.Duration) time.Duration) Task

TimedFailF is like TimedFail, but use function instead.

The function accepts actual execution time, and returns how long it should wait.

func (Task) With added in v0.1.0

func (t Task) With(modder CtxMod) Task

With creates a task that the context is derived using modder before running t.

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.

Jump to

Keyboard shortcuts

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