futures

package module
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Dec 15, 2022 License: MIT Imports: 4 Imported by: 2

README

Go-Futures

GitHub release PkgGoDev

An easy to use generic future implementation in Go.

Install
go get github.com/Allan-Jacobs/go-futures@latest
Example
package main

import (
	"fmt"
	"net/http"

	"github.com/Allan-Jacobs/go-futures/futures"
)

// HTTPGetAsync wraps http.Get into a future based api
func HTTPGetAsync(url string) futures.Future[*http.Response] {
	return futures.GoroutineFuture(func() (*http.Response, error) {
		return http.Get(url)
	})
}

func main() {
	// run futures simultaneously and await aggregated results
	responses, err := futures.All(
		HTTPGetAsync("https://go.dev"),
		HTTPGetAsync("https://pkg.dev"),
	).Await()
	if err != nil {
		fmt.Println("Error:", err)
	}
	for _, res := range responses {
		fmt.Println(res.Request.URL, res.Status)
	}
}
License

go-futures is MIT Licensed

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrCancelled = errors.New("future cancelled")

An error that happens when a future gets cancelled

View Source
var ErrReadFromClosedChannel = errors.New("cannot <- from closed channel")

An error happens when ChannelFuture is called on a closed channel

View Source
var ErrReadFromNilChannel = errors.New("cannot <- from nil channel")

An error happens when ChannelFuture is called on a nil channel

View Source
var ErrTimeout = errors.New("future timed out")

An error that happens when a future times out

Functions

func CompletableFuture added in v0.3.0

func CompletableFuture[T any]() (Completer[T], Future[T])

Returns a Completer and a Future. The Future is settled when the Completer or Error gets called on the Completer

func OnReject added in v0.3.0

func OnReject[T any](future Future[T], callback Rejector)

OnReject takes a Future[T] and executes the callback in another goroutine if the future rejects

func OnResolve added in v0.3.0

func OnResolve[T any](future Future[T], callback Resolver[T])

OnResolve takes a Future[T] and executes the callback in another goroutine if the future resolves

func OnSettled added in v0.3.0

func OnSettled[T any](future Future[T], callback func(T, error))

OnSettled takes a Future[T] and executes the callback in another goroutine when it is settled

Types

type CancellableFuture

type CancellableFuture[T any] interface {
	Future[T]
	// Cancel attempts to cancel the future, and returns true if it is cancelled.
	// Cancel will return false if the future has already completed.
	Cancel() bool
}

A future that can be cancelled

func CancellableGoroutineFuture

func CancellableGoroutineFuture[T any](f func(signal <-chan struct{}) (T, error)) CancellableFuture[T]

This runs f in a goroutine and returns a future that settles the the result of f. The goroutine should cancel its operation when it receives a value on signal This future can be cancelled.

func SleepFuture

func SleepFuture(duration time.Duration) CancellableFuture[struct{}]

A future that resolves after the duration. This future may take longer than duration, but is guaranteed to take at least duration.

type Completer added in v0.3.0

type Completer[T any] struct {
	// contains filtered or unexported fields
}

func (Completer[T]) Complete added in v0.3.0

func (c Completer[T]) Complete(val T)

func (Completer[T]) Error added in v0.3.0

func (c Completer[T]) Error(err error)

type ErrorAggregation

type ErrorAggregation interface {
	error
	Errors() []error
}

An aggregate error type

type Future

type Future[T any] interface {
	// Await blocks the current goroutine until the future is settled.
	// Await may be called by different goroutines concurrently, and it may be called multiple times.
	Await() (T, error)
}

A Future[T] represents an asynchronous operation. The Future[T] implementations in this module follow a "push" model. This means that futures immediately start running their operations as soon as they are created. [Future[T].Await] only blocks until the future is settled and may be called multiple times across different goroutines.

The future follows a basic state machine. The future starts as pending, and after it "settles" or completes, it ends as either resolved or rejected. Resolved futures return a nil error when awaited, and indicate success. Rejected futures return a non-nil error when awaited, which is a failure that should be handled.

Example:

package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/Allan-Jacobs/go-futures/futures"
)

// GetAsync wraps [http.Get] in a future
func GetAsync(url string) futures.Future[*http.Response] {
	return futures.GoroutineFuture(func() (*http.Response, error) {
		return http.Get(url)
	})
}

func main() {
	// run GetAsync concurrently
	results, err := futures.All(
		GetAsync("https://go.dev"),
		GetAsync("https://pkg.go.dev"),
	).Await()

	if err != nil { // evaluates to true when the future rejects
		log.Fatal("Error: ", err.Error())
	}

	for _, res := range results {
		fmt.Printf("Got response from %s %s\n", res.Request.URL, res.Status)
	}
}

func All

func All[T any](futures ...Future[T]) Future[[]T]

All settles to a slice of results when all the futures resolve, or returns an error with any futures that reject

func AllSettled added in v0.3.0

func AllSettled[T any](futures []Future[T]) Future[[]struct {
	val T
	err error
}]

func Any

func Any[T any](futures ...Future[T]) Future[T]

Any settles to the first future to resolve, or rejects with an error aggregation if none resolve

func Chain

func Chain[T, O any](future Future[T], mapper func(T) (O, error)) Future[O]

Chain takes a Future[T] and returns a future that is mapped with mapper, propagating any errors that occur

func ChainErr

func ChainErr[T, O any](future Future[T], mapper func(T, error) (O, error)) Future[O]

Chain takes a Future[T] and returns a future that is mapped with mapper, passing any errors that occurred to mapper

func ChannelFuture

func ChannelFuture[T any](ch <-chan T) Future[T]

A future that resolves to the next value of the channel

func Flatten added in v0.3.0

func Flatten[T any](future Future[Future[T]]) Future[T]

Returns a future that resolves the same value as the inner future, unless the outer future errors, in which case returned the future errors

func GoroutineFuture

func GoroutineFuture[T any](f func() (T, error)) Future[T]

This runs f in a goroutine and returns a future that settles the the result of f

func PromiseLikeFuture

func PromiseLikeFuture[T any](f func(resolve Resolver[T], reject Rejector)) Future[T]

A future type similar to JavaScript's Promise This runs f in a different goroutine, so be aware of potential race conditions. if resolve or reject are called multiple times, they are no-ops. However multiple calls are discouraged, as it acquires a mutex every call.

func Race

func Race[T any](futures ...Future[T]) Future[T]

Race settles to the first future to finish

func RejectedFuture added in v0.3.0

func RejectedFuture[T any](err error) Future[T]

Returns a future that rejects with err

func ResolvedFuture added in v0.3.0

func ResolvedFuture[T any](value T) Future[T]

Returns a future that resolves to value

func Timeout

func Timeout[T any](future Future[T], timeout time.Duration) Future[T]

Returns a Future that times out with ErrTimeout if future does not settle before timeout

type Rejector

type Rejector func(error)

type Resolver

type Resolver[T any] func(T)

Jump to

Keyboard shortcuts

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