kargar

package module
v0.0.0-...-5f62bd1 Latest Latest
Warning

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

Go to latest
Published: Aug 7, 2019 License: MIT Imports: 7 Imported by: 5

README

Kargar GoDoc

Kagrar is a concurrency-aware task harness and dependency management with first-class support for Deadlines, Cancelation, and task-labeled logging.

Kargar allows you to cancel tasks.

ctx, cancel := context.WithCancel(context.Background())

b := kargar.NewBuild(ctx)

b.Add(kargar.Task{

	Name:  "say-hello",
	Usage: "This tasks is self-documented, it says hello for every second.",

	Action: func(ctx context.Context) error {

		second := time.NewTicker(time.Second)

		for {
			select {

			case <-second.C:
				ctx.Info("Hello!")
			case <-ctx.Done():
				return ctx.Err()
			}
		}
	},
})

go func() {
	time.Sleep(4 * time.Second)
	cancel()
}()

err := b.Run("say-hello")
if err != nil {
	log.Println(err)
}
INFO[0001] Hello!                                        task=say-hello
INFO[0002] Hello!                                        task=say-hello
INFO[0003] Hello!                                        task=say-hello
INFO[0004] Hello!                                        task=say-hello
ERRO[0004] context canceled

To avoid race-conditions, there will be one and only one instance of any given task running at any given time.

b := kargar.New()

b.Add(
	kargar.Task{

		Name:  "slow-dependency",
		Usage: "This is a slow task, takes 3 seconds before it prints time.",

		Action: func(ctx context.Context) error {

			ctx.Warn("I am pretty slow.")
			for {
				select {

				case now := <-time.After(3 * time.Second):
					ctx.Infof("Time is %s", now.Format(time.Kitchen))
					return nil
				case <-ctx.Done():
					return ctx.Err()
				}
			}
		},
	},

	kargar.Task{
		Name:   "a",
		Usage:  "This task depends on 'slow-dependency.'",
		Deps:   []string{"slow-dependency"},
		Action: kargar.Noop(),
	},

	kargar.Task{
		Name:   "b",
		Usage:  "This task depends on 'slow-dependency.'",
		Deps:   []string{"slow-dependency"},
		Action: kargar.Noop(),
	},

	kargar.Task{
		Name:   "c",
		Usage:  "This task depends on 'slow-dependency.'",
		Deps:   []string{"slow-dependency"},
		Action: kargar.Noop(),
	},
)

ctx := b.Context()
var wg sync.WaitGroup

for _, t := range []string{"a", "b", "c"} {
	wg.Add(1)
	go func(t string) {
		defer wg.Done()
		err := b.Run(t)
		if err != nil {
			ctx.Error(err)
		}
	}(t)
}

wg.Wait()
WARN[0000] I am pretty slow.                             parent=c task=slow-dependency
INFO[0003] Time is 2:14PM                                parent=c task=slow-dependency
WARN[0003] I am pretty slow.                             parent=b task=slow-dependency
INFO[0006] Time is 2:14PM                                parent=b task=slow-dependency
WARN[0006] I am pretty slow.                             parent=a task=slow-dependency
INFO[0009] Time is 2:14PM                                parent=a task=slow-dependency

Kar

To build and run Kargar tasks from CLI, see kar.

LICENSE

MIT.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var BuildHelpTemplate = `` /* 394-byte string literal not displayed */

BuildHelpTemplate holds the template used for generating the help message for a build TODO: Move this to /kar?

View Source
var ErrorNoSuchTask = fmt.Errorf("No Such Task")

ErrorNoSuchTask is returned when any of the given tasks does not exist.

View Source
var HelpTemplate *template.Template

Help templates hold both Build and Task help templates.

View Source
var TaskHelpTemplate = `` /* 239-byte string literal not displayed */

TaskTemplate holds the template used to generate the help message for a specific task.

Functions

This section is empty.

Types

type Action

type Action func(context.Context) error

Action is a function that is called when a task is run.

func Noop

func Noop() Action

Noop is an Action that does nothing and returns `nil` immediately. For clarity and to avoid weird bugs, every task must have an Action Noop is provided for tasks that are only used to group a collection of tasks as dependency.

type Build

type Build struct {
	Meta Meta
	// contains filtered or unexported fields
}

Build is a simple build harness that you can register tasks and their dependencies and then run them.

func New

func New() *Build

New returns a Build with a contex with no deadline or values and is never canceled.

func NewBuild

func NewBuild(ctx context.Context) *Build

NewBuild returns a Build using the provided Context.

func (*Build) Add

func (b *Build) Add(tasks ...Task) error

Add registers the provided tasks to the build. Circular Dependencies are not allowed.

func (*Build) Context

func (b *Build) Context() context.Context

Context returns the current builds context. Useful for loging.

func (*Build) Run

func (b *Build) Run(tasks ...string) error

Run runs the provided lists of tasks.

func (*Build) RunFor

func (b *Build) RunFor(ctx context.Context, tasks ...string) error

RunFor runs a task using an alternative context. This this is typically useful when you want to dynamically invoked tasks from another task but still maintain proper context hireachy.

type Meta

type Meta struct {
	// The name of the program. Defaults to os.Args[0]
	Name string
	// Description of the program.
	Usage string
	// Version of the program
	Version string
	// Author
	Author string
	// Author e-mail
	Email string

	// License
	License string
}

Meta holds information about the build.

type Task

type Task struct {
	// Taks name
	Name string
	// A short description of the task.
	Usage string
	// A long explanation of how the task works.
	Description string
	// List of dependencies.
	// When running a task, the dependencies will be run in the order
	Deps []string
	// The function to call when the task is invoked.
	Action Action
}

Task holds the meta information and an action.

Jump to

Keyboard shortcuts

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