nursery

package module
v0.0.0-...-b0500b1 Latest Latest
Warning

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

Go to latest
Published: Aug 31, 2023 License: MPL-2.0 Imports: 4 Imported by: 3

README

Nursery

Nursery is an implementation of the concurrency primitive of the same name from Nathaniel J. Smith's (a.k.a @vorpalsmith on Twitter, njsmith on GitHub) 2018 blog post on structured concurrency. This is the same concept as in Smith's Python library Trio.

Nurseries are a control flow structure for concurrent execution that provides (as much as possible) the same guarantee of other control flow mechanisms: program execution enters the structure in one place, and exits the structure in one place. What happens in between those places can happen concurrently (or in parallel) and is guaranteed (as much as possible) to be complete by the time the Nursery is closed again.

Nursery should be considered ALPHA quality software.

Quick Start

To use a Nursery, there are two types of function to provide: an Initializer which starts some number of Tasks.

package main

import (
    "context"
    "fmt"
    "time"
    "github.com/jsocol/nursery"
)

func main() {
    ctx := context.Background()
    err := nursery.Open(ctx, func(n nursery.Nursery) error {
        n.Start(func(context.Context) error {
            time.Sleep(1 * time.Second)
            fmt.Println("task 1")
            return nil
        })

        n.Start(func(context.Context) error {
            fmt.Println("task 2, will error")
            return fmt.Errorf("always errors")
        })

        return nil
    })
    // both tasks have completed
    if err != nil {
        fmt.Println("Error! " + err)
    }
}

Unlike sync.WaitGroup, tasks can be added to the Nursery at any point during its lifetime. Attempting to use a Nursery's Start method after Open has returned will return an ErrStopped.

Context-aware Tasks

All Task functions are passed a context.Context that is a child of the context passed to Open. Task functions should use the given context to control any cancellable operations they start, like network activity. In the event of an error from one of the Tasks, these contexts will be canceled, and the initial error will be returned.

The initial context passed to Open can itself be cancellable or with a timeout or deadline.

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrStopped = errors.New("nursery is stopping or stopped")

Functions

func Open

func Open(ctx context.Context, init Initializer) error

Open creates a new Nursery that can be used to start Tasks. All started Tasks are guaranteed to be completed by the time Open returns. In terms of the Go memory model, all Tasks "synchronize before" Open can complete.

Example
package main

import (
	"context"
	"errors"
	"fmt"
	"time"

	"github.com/jsocol/nursery"
)

func main() {
	ctx := context.Background()

	err := nursery.Open(ctx, func(n nursery.Nursery) error {
		n.Start(func(ctx context.Context) error {
			return errors.New("I always fail")
		})

		n.Start(func(ctx context.Context) error {
			time.Sleep(time.Millisecond)
			fmt.Println("I always happen")
			return nil
		})

		return nil
	})
	if err != nil {
		fmt.Println("Err: " + err.Error())
	}
}
Output:

I always happen
Err: I always fail

Types

type Initializer

type Initializer func(Nursery) error

type Nursery

type Nursery interface {
	Start(Task) error
}

A Nursery is a control flow mechanism for concurrent or parallel tasks.

type Task

type Task func(context.Context) error

A Task is a job

Directories

Path Synopsis
examples
batching module
finite-tasks module

Jump to

Keyboard shortcuts

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