Documentation ¶
Overview ¶
Package tasker provides utilities to background task management to achieve simplicity.
Example (SequenceMixedWithConcurrence) ¶
package main import ( "context" "github.com/adamluzsi/frameless/pkg/tasker" ) func main() { _ = tasker.Sequence( tasker.Concurrence( func() { /* migration task 1 */ }, func() { /* migration task 2 */ }, ), tasker.Concurrence( func() { /* task dependent on migrations */ }, func() { /* task dependent on migrations */ }, func() { /* task dependent on migrations */ }, ), )(context.Background()) }
Output:
Index ¶
- func Main(ctx context.Context, tasks ...Task) error
- type Interval
- type Runnable
- type Task
- func Concurrence[TFN genericTask](tfns ...TFN) Task
- func IgnoreError[TFN genericTask](tfn TFN, errsToIgnore ...error) Task
- func OnError[TFN genericTask, EHFN genericErrorHandler](tfn TFN, ehfn EHFN) Task
- func Sequence[TFN genericTask](tfns ...TFN) Task
- func ToTask[TFN genericTask](tfn TFN) Task
- func WithRepeat[TFN genericTask](interval Interval, tfn TFN) Task
- func WithShutdown[StartFn, StopFn genericTask](start StartFn, stop StopFn) Task
- func WithSignalNotify[TFN genericTask](tfn TFN, shutdownSignals ...os.Signal) Task
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Task ¶
Task is the basic unit of tasker package, that represents an executable work.
Task at its core, is nothing more than a synchronous function. Working with synchronous functions removes the complexity of thinking about how to run your application. Your components become more stateless and focus on the domain rather than the lifecycle management. This less stateful approach can help to make testing your Task also easier.
func Concurrence ¶
func Concurrence[TFN genericTask](tfns ...TFN) Task
Concurrence is construct that allows you to execute a list of Task concurrently. If any of the Task fails with an error, all Task will receive cancellation signal.
Example ¶
package main import ( "context" "github.com/adamluzsi/frameless/pkg/tasker" ) func main() { err := tasker.Concurrence( func(ctx context.Context) error { // concurrent task 1 return nil }, func(ctx context.Context) error { // concurrent task 2 return nil }, ).Run(context.Background()) _ = err }
Output:
func IgnoreError ¶
func OnError ¶
func OnError[TFN genericTask, EHFN genericErrorHandler](tfn TFN, ehfn EHFN) Task
Example ¶
package main import ( "context" "github.com/adamluzsi/frameless/pkg/logger" "github.com/adamluzsi/frameless/pkg/tasker" ) func main() { withErrorHandling := tasker.OnError( func(ctx context.Context) error { return nil }, // task func(ctx context.Context, err error) error { logger.Error(ctx, err.Error()); return nil }, // error handling ) _ = withErrorHandling }
Output:
func Sequence ¶
func Sequence[TFN genericTask](tfns ...TFN) Task
Example ¶
package main import ( "context" "github.com/adamluzsi/frameless/pkg/tasker" ) func main() { err := tasker.Sequence( func(ctx context.Context) error { // first task to execute return nil }, func(ctx context.Context) error { // follow-up task to execute return nil }, ).Run(context.Background()) _ = err }
Output:
func WithRepeat ¶
WithRepeat will keep repeating a given Task until shutdown is signaled. It is most suitable for Task(s) meant to be short-lived and executed continuously until the shutdown signal.
Example ¶
package main import ( "context" "github.com/adamluzsi/frameless/pkg/tasker" "github.com/adamluzsi/frameless/pkg/tasker/schedule" "log" "time" ) func main() { task := tasker.WithRepeat(schedule.Interval(time.Second), func(ctx context.Context) error { // I'm a short-lived task, and prefer to be constantly executed, // Repeat will keep repeating me every second until shutdown is signaled. return nil }) ctx, cancel := context.WithTimeout(context.Background(), time.Hour) defer cancel() if err := task(ctx); err != nil { log.Println("ERROR", err.Error()) } }
Output:
func WithShutdown ¶
func WithShutdown[StartFn, StopFn genericTask](start StartFn, stop StopFn) Task
WithShutdown will combine the start and stop/shutdown function into a single Task function. It supports a graceful shutdown period; upon reaching the deadline, it will cancel the context passed to the shutdown function. WithShutdown makes it easy to use components with graceful shutdown support as a Task, such as the http.Server.
tasker.WithShutdown(srv.ListenAndServe, srv.Shutdown)
Example ¶
package main import ( "context" "github.com/adamluzsi/frameless/pkg/tasker" "log" ) func main() { task := tasker.WithShutdown( func(ctx context.Context) error { // start working <-ctx.Done() return nil }, func(ctx context.Context) error { // graceful stop for work <-ctx.Done() return nil }, ) ctx, cancel := context.WithCancel(context.Background()) // listen to a cancellation signal and then call the cancel func // or use ShutdownManager. _ = cancel if err := task(ctx); err != nil { log.Println("ERROR", err.Error()) } }
Output:
Example (HttpServer) ¶
package main import ( "context" "github.com/adamluzsi/frameless/pkg/tasker" "log" "net/http" ) func main() { srv := http.Server{ Addr: "localhost:8080", Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusTeapot) }), } httpServerTask := tasker.WithShutdown( tasker.IgnoreError(srv.ListenAndServe, http.ErrServerClosed), srv.Shutdown, ) if err := tasker.WithSignalNotify(httpServerTask)(context.Background()); err != nil { log.Println("ERROR", err.Error()) } }
Output:
func WithSignalNotify ¶
Example ¶
package main import ( "context" "github.com/adamluzsi/frameless/pkg/tasker" "log" "net/http" ) func main() { srv := http.Server{ Addr: "localhost:8080", Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusTeapot) }), } task := tasker.WithShutdown(srv.ListenAndServe, srv.Shutdown) task = tasker.WithSignalNotify(task) if err := task(context.Background()); err != nil { log.Println("ERROR", err.Error()) } }
Output: