fun

package module
v0.9.4 Latest Latest
Warning

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

Go to latest
Published: May 18, 2023 License: Apache-2.0 Imports: 9 Imported by: 17

README

fun -- Go Generic Functions and Tools

Go Reference

fun is a simple, well tested, zero-dependency, collection of packages with generic function, tools, patterns, and the kind of thing you could write one-offs for but shouldn't.

Packages:

  • erc (error collecting.)
  • itertool (iterator tools.)
  • pubsub (message broker and queues.)
  • set (generic ordered and unordered sets.)
  • seq (generic linked lists.)
  • srv (service orchestration and management framework.)
  • adt (strongly atomic data types and operations.)

For more information, see the documentation, but of general interest:

  • In itertools and with fun.Iterator, an iterator framework and tools for interacting with iterators and generators.
  • In pubsub, a channel-based message broker (for one-to-many channel patterns), with several backend patterns for dealing with load-shedding and message distribution patterns.
  • In erc, an error collector implementation for threadsafe error aggregation and introspection, particularly in worker-pool, applications.
  • In set, a Set type, with ordered and unordered implementations.
  • Queue and Deque implementations (in pubsub) that provide thread-safe linked-list based implementations and Wait methods to block until new items added.
  • In seq, general purpose linked list implementations, with a healthy feature set and flexible interface.
  • In srv, a service orchestration toolkit and lifecycle tools.
  • In adt, a collection of Atomic/Pool/Map operations that use generics to provide strongly typed interfaces for common operations.

Contributions welcome, the general goals of the project:

  • superior API ergonomics.
  • great high-level abstractions.
  • obvious and clear implementations.
  • minimal dependencies.

Have fun!

Documentation

Overview

Package fun is a zero-dependency collection of tools and idoms that takes advantage of generics. Iterators, error handling, a native-feeling Set type, and a simple pub-sub framework for distributing messages in fan-out patterns.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrInvariantViolation is the root error of the error object that is
	// the content of all panics produced by the Invariant helper.
	ErrInvariantViolation = errors.New("invariant violation")
	// ErrRecoveredPanic is at the root of any error returned by a
	// function in the fun package that recovers from a panic.
	ErrRecoveredPanic = errors.New("recovered panic")
)
View Source
var ErrSkippedNonBlockingChannelOperation = internal.ErrSkippedNonBlockingChannelOperation

ErrSkippedNonBlockingChannelOperation is returned when sending into a channel, in a non-blocking context, when the channel was full and the send or receive was therefore skipped.

Functions

func Apply added in v0.9.4

func Apply[T any](fn func(T) T, in []T) []T

Apply processes an input slice, with the provided function, returning a new slice that holds the result.

func Check added in v0.3.0

func Check(fn func()) (err error)

Check, like Safe, runs a function without arguments that does not produce an error, and, if the function panics, converts it into an error.

func Contains added in v0.9.1

func Contains[T comparable](item T, slice []T) bool

Contain returns true if an element of the slice is equal to the item.

func Count added in v0.9.3

func Count[T any](ctx context.Context, iter Iterator[T]) int

Count returns the number of items observed by the iterator. Callers should still manually call Close on the iterator.

func Invariant added in v0.3.0

func Invariant(cond bool, args ...any)

Invariant panics if the condition is false Invariant panics, passing an error that is rooted by ErrInvariantViolation.

func InvariantCheck added in v0.6.0

func InvariantCheck(fn func() error, args ...any)

InvariantCheck calls the function and if it returns an error panics with an ErrInvariantViolation error, wrapped with the error of the function, and any annotation arguments.

func InvariantMust added in v0.6.0

func InvariantMust(err error, args ...any)

InvariantMust raises an invariant error if the error is not nil. The content of the panic is both--via wrapping--an ErrInvariantViolation and the error itself.

func Is

func Is[T any](in any) bool

Is a generic version of `errors.Is` that takes advantage of the Unwrap function, and is useful for checking if an object of an interface type is or wraps an implementation of the type parameter.

func IsInvariantViolation added in v0.3.0

func IsInvariantViolation(r any) bool

IsInvariantViolation returns true if the argument is or resolves to ErrInvariantViolation.

func IsWrapped added in v0.8.0

func IsWrapped[T any](in T) bool

IsWrapped returns true if the object is wrapped (e.g. implements an Unwrap() method returning its own type). and false otherwise.

func IsZero added in v0.8.0

func IsZero[T comparable](in T) bool

IsZero returns true if the input value compares "true" to the zero value for the type of the argument. If the type implements an IsZero() method (e.g. time.Time), then IsZero returns that value, otherwise, IsZero constructs a zero valued object of type T and compares the input value to the zero value.

func IterateOne added in v0.8.5

func IterateOne[T any](ctx context.Context, iter Iterator[T]) (T, error)

IterateOne, like ReadOne reads one value from the iterator, and returns it. The error values are either a context cancelation error if the context is canceled, or io.EOF if there are no elements in the iterator. The semantics of fun.IterateOne and fun.ReadOne are the same.

IterateOne does not provide atomic exclusion if multiple calls to the iterator or IterateOne happen concurrently; however, the adt.NewIterator wrapper, and most of the iterator implementations provided by the fun package, provide a special case which *does* allow for safe and atomic concurrent use with fun.IterateOne.

func IterateOneBlocking added in v0.9.0

func IterateOneBlocking[T any](iter Iterator[T]) (T, error)

IterateOneBlocking has the same semantics as IterateOne except it uses a blocking context, and if the iterator is blocking and there are no more items, IterateOneBlocking will never return. Use with caution, and in situations where you understand the iterator's implementation.

func Must

func Must[T any](arg T, err error) T

Must wraps a function that returns a value and an error, and converts the error to a panic.

func MustBeOk added in v0.8.6

func MustBeOk[T any](out T, ok bool) T

MustBeOk raises an invariant violation if the ok value is false, and returns the first value if the second value is ok. Useful as in:

out := fun.MustBeOk(func() (string ok) { return "hello world", true })

func Observe added in v0.7.0

func Observe[T any](ctx context.Context, iter Iterator[T], fn Observer[T]) (err error)

Observe processes an iterator calling the observer function for every element in the iterator and retruning when the iterator is exhausted. Take care to ensure that the Observe function does not block.

The error returned captures any panics encountered as an error, as well as the output of the Close() operation. Observe will not add a context cancelation error to its error, though the observed iterator may return one in its close method.

func Protect added in v0.8.5

func Protect[I any, O any](fn func(I) (O, error)) func(I) (O, error)

Protect wraps a function with a panic handler, that will parse and attach the content of the pantic to the error output (while maintaining the functions orginial error.) All handled panics will be annotated with fun.ErrRecoveredPanic.

func ReadOne added in v0.7.0

func ReadOne[T any](ctx context.Context, ch <-chan T) (T, error)

ReadOnce reads one item from the channel, and returns it. ReadOne returns early if the context is canceled (ctx.Err()) or the channel is closed (io.EOF).

func Safe

func Safe[T any](fn func() T) (out T, err error)

Safe runs a function with a panic handler that converts the panic to an error.

func Unwind added in v0.8.0

func Unwind[T any](in T) []T

Unwind uses the Unwrap operation to build a list of the "wrapped" objects.

func Unwrap

func Unwrap[T any](in T) T

Unwrap is a generic equivalent of the `errors.Unwrap()` function for any type that implements an `Unwrap() T` method. useful in combination with Is.

func WhenCall added in v0.8.5

func WhenCall(cond bool, op func())

WhenCall runs a function when condition is true, and is a noop otherwise.

func WhenDo added in v0.8.5

func WhenDo[T any](cond bool, op func() T) T

WhenDo calls the function when the condition is true, and returns the result, or if the condition is false, the operation is a noop, and returns zero-value for the type.

func Zero added in v0.8.0

func Zero[T any](T) T

Zero returns the zero-value for the type T of the input argument.

func ZeroOf added in v0.8.0

func ZeroOf[T any]() T

ZeroOf returns the zero-value for the type T specified as an argument.

func ZeroWhenNil added in v0.8.0

func ZeroWhenNil[T any](val any) T

ZeroWhenNil takes a value of any type, and if that value is nil, returns the zero value of the specified type. Otherwise, ZeroWhenNil coerces the value into T and returns it. If the input value does not match the output type of the function, ZeroWhenNil panics with an ErrInvariantViolation.

Types

type ChannelOp added in v0.9.4

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

ChannelOp is a wrapper around a channel, to make it easier to write clear code that uses and handles basic operations with single channels. From a high level an operation might look like:

ch := make(chan string)
err := fun.Blocking().Send()

func Blocking added in v0.8.5

func Blocking[T any](ch chan T) ChannelOp[T]

Blocking produces a blocking Send instance. All Send/Check/Ignore operations will block until the context is canceled, the channel is canceled, or the send succeeds.

func NonBlocking added in v0.8.5

func NonBlocking[T any](ch chan T) ChannelOp[T]

NonBlocking produces a send instance that performs a non-blocking send.

The Send() method, for non-blocking sends, will return ErrSkipedNonBlockingSend if the channel was full and the object was not sent.

func (ChannelOp[T]) Recieve added in v0.9.4

func (op ChannelOp[T]) Recieve() Receive[T]

func (ChannelOp[T]) Send added in v0.9.4

func (op ChannelOp[T]) Send() Send[T]

type Iterator

type Iterator[T any] interface {
	Next(context.Context) bool
	Close() error
	Value() T
}

Iterator provides a safe, context-respecting iterator paradigm for iterable objects, along with a set of consumer functions and basic implementations.

The itertool package provides a number of tools and paradigms for creating and processing Iterator objects, including Generators, Map and Reduce as well as Split and Merge to combine or divide iterators.

In general, Iterators cannot be safe for access from multiple concurrent goroutines, because it is impossible to synchronize calls to Next() and Value(); however, itertool.Range() and itertool.Split() provide support for these workloads.

func BuildPairs added in v0.9.4

func BuildPairs[K comparable, V any](ctx context.Context, iter Iterator[V], keyf func(V) K) Iterator[Pair[K, V]]

Pair constructs an iterator of pairs, which it builds from a sequence of values, generating the keys using the provided key function.

func Filter added in v0.9.3

func Filter[T any](iter Iterator[T], check func(T) bool) Iterator[T]

Filter passes every item in the input iterator and, if the check function returns true propogates it to the output iterator. There is no buffering, and check functions should return quickly. For more advanced use, consider using itertool.Map()

func Generator added in v0.8.5

func Generator[T any](op func(context.Context) (T, error)) Iterator[T]

Generator creates an iterator that produces new values, using the generator function provided. This implementation does not create any background go routines, and the iterator will produce values until the function returns an error or the Close() method is called. Any non-nil error returned by the generator function is propagated to the close method, as long as it is not a context cancellation error or an io.EOF error.

func PairKeys added in v0.9.3

func PairKeys[K comparable, V any](iter Iterator[Pair[K, V]]) Iterator[K]

PairKeys converts an iterator of Pairs to an iterator of its keys.

func PairValues added in v0.9.3

func PairValues[K comparable, V any](iter Iterator[Pair[K, V]]) Iterator[V]

PairValues converts an iterator of pairs to an iterator of its values.

func Transform added in v0.8.5

func Transform[I, O any](iter Iterator[I], op func(in I) (O, error)) Iterator[O]

Transform processes the input iterator of type I into an output iterator of type O. It's implementation uses the Generator, will continue producing values as long as the input iterator produces values, the context isn't canceled, or

func UnwindIterator added in v0.9.4

func UnwindIterator[T any](root T) Iterator[T]

UnwindIterator unwinds an object as in unwind but produces the result as an Iterator. The iterative approach may be more ergonomic in some situations, but also eliminates the need to create a copy the unwound stack of objects to a slice.

type Map added in v0.9.3

type Map[K comparable, V any] map[K]V

Map is just a generic type wrapper around a map, mostly for the purpose of being able to interact with Pair[K,V] objects and Iterators.

All normal map operations are still accessible, these methods exist to provide accessible function objects for use in contexts where that may be useful and to improve the readability of some call sites, where default map access may be awkward.

func Mapify added in v0.9.3

func Mapify[K comparable, V any](in map[K]V) Map[K, V]

Mapify provides a constructor that will produce a fun.Map without specifying types.

func (Map[K, V]) Add added in v0.9.3

func (m Map[K, V]) Add(k K, v V)

Add adds a key value pair directly to the map.

func (Map[K, V]) AddPair added in v0.9.3

func (m Map[K, V]) AddPair(p Pair[K, V])

AddPair adds a Pair object to the map.

func (Map[K, V]) Append added in v0.9.3

func (m Map[K, V]) Append(pairs ...Pair[K, V])

Append adds a sequence of Pair objects to the map.

func (Map[K, V]) Check added in v0.9.4

func (m Map[K, V]) Check(key K) bool

Check returns true if the value K is in the map.

func (Map[K, V]) Consume added in v0.9.3

func (m Map[K, V]) Consume(ctx context.Context, iter Iterator[Pair[K, V]])

Consume adds items to the map from an iterator of Pair objects. Existing values for K are always overwritten.

func (Map[K, V]) ConsumeMap added in v0.9.3

func (m Map[K, V]) ConsumeMap(in Map[K, V])

ConsumeMap adds all the keys from the input map the map.

func (Map[K, V]) ConsumeSlice added in v0.9.3

func (m Map[K, V]) ConsumeSlice(in []V, keyf func(V) K)

ConsumeSlice adds a slice of values to the map, using the provided function to generate the key for the value. Existing values in the map are overridden.

func (Map[K, V]) ConsumeValues added in v0.9.3

func (m Map[K, V]) ConsumeValues(ctx context.Context, iter Iterator[V], keyf func(V) K)

ConsumeValues adds items to the map, using the function to generate the keys for the values.

func (Map[K, V]) Extend added in v0.9.3

func (m Map[K, V]) Extend(pairs Pairs[K, V])

Extend adds a sequence of Pairs to the map.

func (Map[K, V]) Get added in v0.9.4

func (m Map[K, V]) Get(key K) V

Get returns the value from the map, and is the same thing as:

foo := mp[key]

If the key is not present in the map, as with a normal map, this is the zero value for V.

func (Map[K, V]) Iterator added in v0.9.3

func (m Map[K, V]) Iterator() Iterator[Pair[K, V]]

Iterator converts a map into an iterator of fun.Pair objects. The iterator is panic-safe, and uses one go routine to track the progress through the map. As a result you should always, either exhaust the iterator, cancel the context that you pass to the iterator OR call iterator.Close().

To use this iterator the items in the map are not copied, and the iteration order is randomized following the convention in go.

Use in combination with other iterator processing tools (generators, observers, transformers, etc.) to limit the number of times a collection of data must be coppied.

func (Map[K, V]) Keys added in v0.9.3

func (m Map[K, V]) Keys() Iterator[K]

Keys provides an iterator over just the keys in the map.

func (Map[K, V]) Len added in v0.9.3

func (m Map[K, V]) Len() int

Len returns the length. It is equivalent to len(Map), but is provided for consistency.

func (Map[K, V]) Load added in v0.9.4

func (m Map[K, V]) Load(key K) (V, bool)

Load returns the value in the map for the key, and an "ok" value which is true if that item is present in the map.

func (Map[K, V]) Pairs added in v0.9.3

func (m Map[K, V]) Pairs() Pairs[K, V]

Pairs exports a map a Pairs object, which is an alias for a slice of Pair objects.

func (Map[K, V]) SetDefault added in v0.9.4

func (m Map[K, V]) SetDefault(key K)

SetDefault set's sets the provided key in the map to the zero value for the value type.

func (Map[K, V]) Values added in v0.9.3

func (m Map[K, V]) Values() Iterator[V]

Values provides an iterator over just the values in the map.

type Observer added in v0.8.5

type Observer[T any] func(T)

Observer describes a function that operates on a single object, but returns no output, and is used primarly for side effects, particularly around handling errors or collecting metrics. The Observer implementation here makes it possible to provide panic-safety for these kinds of functions or easily convert to other related types.

func (Observer[T]) Safe added in v0.8.5

func (of Observer[T]) Safe(in T) (err error)

Safe handles any panic encountered during the observer's execution and converts it to an error.

func (Observer[T]) Wait added in v0.8.5

func (of Observer[T]) Wait(in T) WaitFunc

Wait captures a variable and converts an Observer into a wait function that observes the value when the WaitFunc runs.

func (Observer[T]) Worker added in v0.8.5

func (of Observer[T]) Worker(in T) WorkerFunc

Worker captures a variable and returns a worker function which will, when executed, observe the input value. These worker functions, use the Safe-mode of execution.

type Pair added in v0.8.5

type Pair[K comparable, V any] struct {
	Key   K
	Value V
}

Pair represents a key-value pair. Used by the adt synchronized map implementation and the set package to handle ordered key-value pairs.

func MakePair added in v0.8.5

func MakePair[K comparable, V any](k K, v V) Pair[K, V]

MakePair constructs a pair object. This is identical to using the literal constructor but may be more ergonomic as the compiler seems to be better at inferring types in function calls over literal constructors.

type Pairs added in v0.8.5

type Pairs[K comparable, V any] []Pair[K, V]

Pairs implements a collection of key-value pairs.

func MakePairs added in v0.8.5

func MakePairs[K comparable, V any](in ...Pair[K, V]) Pairs[K, V]

MakePairs constructs a Pairs object from a sequence of Pairs. This is identical to using the literal constructor but may be more ergonomic as the compiler seems to be better at inferring types in function calls over literal constructors.

To build Pairs objects from other types, use the Consume methods.

func (*Pairs[K, V]) Add added in v0.8.5

func (p *Pairs[K, V]) Add(k K, v V)

Add adds a new value to the underlying slice. This may add a duplicate key.

func (*Pairs[K, V]) AddPair added in v0.9.3

func (p *Pairs[K, V]) AddPair(pair Pair[K, V])

AddPair adds a single pair to the slice of pairs.

func (Pairs[K, V]) Append added in v0.8.5

func (p Pairs[K, V]) Append(new ...Pair[K, V]) Pairs[K, V]

Append, mirroring the semantics of the built in append() function adds one or more Pair items to a Pairs slice, and returns the new slice without changing the value of the original slice:

p = p.Append(pair, pare, pear)

func (*Pairs[K, V]) Consume added in v0.9.3

func (p *Pairs[K, V]) Consume(ctx context.Context, iter Iterator[Pair[K, V]]) error

Consume adds items from an iterator of pairs to the current Pairs slice.

func (*Pairs[K, V]) ConsumeMap added in v0.9.3

func (p *Pairs[K, V]) ConsumeMap(in map[K]V)

ConsumeMap adds all of the items in a map to the Pairs object.

func (*Pairs[K, V]) ConsumeSlice added in v0.9.3

func (p *Pairs[K, V]) ConsumeSlice(in []V, keyf func(V) K)

ConsumeSlice adds all the values in the input slice to the Pairs object, creating the keys using the function provide.

func (*Pairs[K, V]) ConsumeValues added in v0.9.3

func (p *Pairs[K, V]) ConsumeValues(ctx context.Context, iter Iterator[V], keyf func(V) K) error

ConsumeValues adds all of the values in the input iterator, generating the keys using the function provided.

func (*Pairs[K, V]) Extend added in v0.9.4

func (p *Pairs[K, V]) Extend(toAdd Pairs[K, V])

Extend adds the items from a Pairs object (slice of Pair) without modifying the donating object.

func (Pairs[K, V]) Iterator added in v0.9.3

func (p Pairs[K, V]) Iterator() Iterator[Pair[K, V]]

Iterator return an iterator over each key-value pairs.

func (Pairs[K, V]) Keys added in v0.9.3

func (p Pairs[K, V]) Keys() Iterator[K]

Keys returns an iterator over only the keys in a sequence of iterator items.

func (Pairs[K, V]) Map added in v0.8.5

func (p Pairs[K, V]) Map() map[K]V

Map converts a list of pairs to the equivalent map. If there are duplicate keys in the Pairs list, only the first occurrence of the key is retained.

func (Pairs[K, V]) MarshalJSON added in v0.8.5

func (p Pairs[K, V]) MarshalJSON() ([]byte, error)

MarshalJSON produces a JSON encoding for the Pairs object by first converting it to a map and then encoding that map as JSON. The JSON serialization does not necessarily preserve the order of the pairs object.

func (*Pairs[K, V]) UnmarshalJSON added in v0.8.5

func (p *Pairs[K, V]) UnmarshalJSON(in []byte) error

UnmarshalJSON provides consistent JSON decoding for Pairs objects. It reads a JSON document into a map and converts it to pairs, and appends it to the existing Pairs objects without removing or resetting the current object.

func (Pairs[K, V]) Values added in v0.9.3

func (p Pairs[K, V]) Values() Iterator[V]

Values returns an iterator over only the values in a sequence of iterator pairs.

type Receive added in v0.9.4

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

Receive, wraps a channel fore <-chan T operations. It is the type returned by the Receive() method on ChannelOp. The primary method is Read(), with other methods provided as "self-documenting" helpers.

func (Receive[T]) Check added in v0.9.4

func (ro Receive[T]) Check(ctx context.Context) (T, bool)

Check performs the read operation and converts the error into an "ok" value, returning true if receive was successful and false otherwise.

func (Receive[T]) Drop added in v0.9.4

func (ro Receive[T]) Drop(ctx context.Context) bool

Drop performs a read operation and drops the response. If an item was dropped (e.g. Read would return an error), Drop() returns false, and true when the Drop was successful.

func (Receive[T]) Force added in v0.9.4

func (ro Receive[T]) Force(ctx context.Context) T

Force ignores the error returning only the value from Read. This is either the value sent through the channel, or the zero value for T. Because zero values can be sent through channels, Force does not provide a way to distinguish between "channel-closed" and "received a zero value".

func (Receive[T]) Read added in v0.9.4

func (ro Receive[T]) Read(ctx context.Context) (T, error)

Read performs the read operation according to the blocking/non-blocking semantics of the receive operation.

In general errors are either: io.EOF if channel is closed; a context cancellation error if the context passed to Read() is canceled, or ErrSkippedNonBlockingChannelOperation in the non-blocking case if the channel was empty.

In all cases when Read() returns an error, the return value is the zero value for T.

type Send added in v0.8.5

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

Send provides access to channel send operations, and is contstructed by the Send() method on the channel operation. The primary method is Write(), with other methods provided for clarity.

func (Send[T]) Check added in v0.8.5

func (sm Send[T]) Check(ctx context.Context, it T) bool

Check performs a send and returns true when the send was successful and false otherwise.

func (Send[T]) Ignore added in v0.8.5

func (sm Send[T]) Ignore(ctx context.Context, it T)

Ignore performs a send and omits the error.

func (Send[T]) Write added in v0.9.4

func (sm Send[T]) Write(ctx context.Context, it T) (err error)

Write sends the item into the channel captured by Blocking/NonBlocking returning the appropriate error.

The returned error is nil if the send was successful, and an io.EOF if the channel is closed rather than a panic (as with the equivalent direct operation.) The error value is a context cancelation error when the context is canceled, and for non-blocking sends, if the channel did not accept the write, ErrSkippedNonBlockingChannelOperation is returned.

type WaitFunc added in v0.6.3

type WaitFunc func(context.Context)

WaitFunc is a type of function object that will block until an operation returns or the context is canceled.

func WaitBlocking added in v0.6.5

func WaitBlocking(fn func()) WaitFunc

WaitBlocking is a convenience function to use simple blocking functions into WaitFunc objects. Because these WaitFunc functions do not resepct the WaitFunc context, use with care and caution.

func WaitBlockingObserve added in v0.6.5

func WaitBlockingObserve[T any](observe func(T), wait func() T) WaitFunc

WaitBlockingObserve is a convenience function that creates a WaitFunc that wraps a simple function that returns a single value, and observes that output with the observer function.

Because these WaitFunc functions do not resepct the WaitFunc context, use with care and caution.

func WaitChannel added in v0.6.3

func WaitChannel[T any](ch <-chan T) WaitFunc

WaitChannel converts a channel (typically, a `chan struct{}`) to a WaitFunc. The WaitFunc blocks till it's context is canceled or the channel is either closed or returns one item.

func WaitContext added in v0.6.3

func WaitContext(ctx context.Context) WaitFunc

WaitContext wait's for the context to be canceled before returning. The WaitFunc that's return also respects it's own context. Use this WaitFunc and it's own context to wait for a context to be cacneled with a timeout, for instance.

func WaitForGroup added in v0.8.0

func WaitForGroup(wg *sync.WaitGroup) WaitFunc

WaitForGroup converts a sync.WaitGroup into a fun.WaitFunc.

This operation will leak a go routine if the WaitGroup never returns and the context is canceled. To avoid a leaked goroutine, use the fun.WaitGroup type.

func WaitMerge added in v0.6.3

func WaitMerge(ctx context.Context, iter Iterator[WaitFunc]) WaitFunc

WaitMerge starts a goroutine that blocks on each WaitFunc provided and returns a WaitFunc that waits for all of these goroutines to return. The constituent WaitFunc are passed WaitMerge's context, while the returned WaitFunc respects its own context.

Use itertool.Variadic, itertool.Slice, or itertool.Channel to convert common container types/calling patterns to an iterator.

In combination with erc.CheckWait, you can use WaitMerge to create and pubsub.Queue or pubsub.Deque blocking iterators to create worker pools.

func WaitObserve added in v0.6.3

func WaitObserve[T any](observe Observer[T], ch <-chan T) WaitFunc

WaitObserve passes the output of the channel into the observer function and then returns. If the context is canceled the output of the channel is not observed.

WaitObserve consumes and observes, at most, one item from the channel. Callers must call the WaitFunc.

func WaitObserveAll added in v0.6.3

func WaitObserveAll[T any](observe Observer[T], ch <-chan T) WaitFunc

WaitObserveAll passes the output of the channel into the observer function, waiting for the input channel to be closed or the WaitFunc's context to be canceled. WaitObserveAll does not begin processing the channel until the WaitFunc is called.

func WaitObserveAllCtx added in v0.8.0

func WaitObserveAllCtx[T any](observe func(context.Context, T), ch <-chan T) WaitFunc

WaitObserveAllCtx passes the output of the channel into the observer function with a context, waiting for the input channel to be closed or the WaitFunc's context to be canceled. WaitObserveAll does not begin processing the channel until the WaitFunc is called.

func (WaitFunc) Add added in v0.8.0

func (wf WaitFunc) Add(ctx context.Context, wg *WaitGroup)

Add starts a goroutine that waits for the WaitFunc to return, incrementing and decrementing the sync.WaitGroup as appropriate. The execution of the wait fun blocks on Add's context.

func (WaitFunc) Block added in v0.6.3

func (wf WaitFunc) Block()

Block runs the WaitFunc with a context that will never be canceled.

func (WaitFunc) BlockSignal added in v0.8.0

func (wf WaitFunc) BlockSignal() <-chan struct{}

BlockSignal runs the WaitFunc in a background goroutine and returns a signal channel that is closed when the operation completes. As in Block() the WaitFunc is passed a background context that is never canceled.

Callers are responsble for handling the (potential) panic in the WaitFunc.

func (WaitFunc) Check added in v0.9.0

func (wf WaitFunc) Check() WorkerFunc

Check converts a wait function into a WorkerFunc, running the wait function inside of a Check() function, which catches panics and turns them into the worker function's errors. If the context errors, the Check function's error also propogates a merged error that includes the context's cancelation error

func (WaitFunc) Run added in v0.8.0

func (wf WaitFunc) Run(ctx context.Context)

Run is equivalent to calling the wait function directly, except the context passed to the function is always canceled when the wait function returns.

func (WaitFunc) Safe added in v0.9.3

func (wf WaitFunc) Safe() WorkerFunc

Safe produces a worker function that catches. This is the same as WaitFunc.Check() except check will also propgate the context error, which this WorkerFunc will not.

func (WaitFunc) Signal added in v0.8.0

func (wf WaitFunc) Signal(ctx context.Context) <-chan struct{}

Signal runs the WaitFunc in a goroutine and returns a signal channel that is canceled when the function completes. Useful for bridging the gap between interfaces and integration that use channels and functions.

Callers are responsble for handling the (potential) panic in the WaitFunc.

func (WaitFunc) WithTimeout added in v0.6.6

func (wf WaitFunc) WithTimeout(timeout time.Duration)

WithTimeout runs the WaitFunc with an explicit timeout.

func (WaitFunc) WithTimeoutSignal added in v0.8.0

func (wf WaitFunc) WithTimeoutSignal(timeout time.Duration) <-chan struct{}

WithTimeoutSignal executes the WaitFunc as in WithTimeout, but returns a singal channel that is closed when the task completes.

Callers are responsble for handling the (potential) panic in the WaitFunc.

func (WaitFunc) Worker added in v0.8.0

func (wf WaitFunc) Worker() WorkerFunc

Worker converts a wait function into a WorkerFunc. If the context is canceled, the worker function returns the context's error. The worker function also captures the wait functions panic and converts it to an error.

type WaitGroup added in v0.6.3

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

WaitGroup works like sync.WaitGroup, except that the Wait method takes a context (and can be passed as a fun.WaitFunc). The implementation is exceptionally simple. The only constraint, like sync.WaitGroup, is that you can never modify the value of the internal counter such that it is negative, event transiently. The implementation does not require background resources aside from Wait, which creates a single goroutine that lives for the entire time that Wait is running, but no other background resources are created. Multiple copies of Wait can be safely called at once, and the WaitGroup is reusable more than once.

This implementation is about 50% slower than sync.WaitGroup after informal testing. It provides a little extra flexiblity and introspection, with similar semantics, that may be worth the additional performance hit.

func (*WaitGroup) Add added in v0.8.0

func (wg *WaitGroup) Add(num int)

Add modifies the internal counter. Raises an ErrInvariantViolation error if any modification causes the internal coutner to be less than 0.

func (*WaitGroup) Done added in v0.8.0

func (wg *WaitGroup) Done()

Done marks a single operation as done.

func (*WaitGroup) IsDone added in v0.8.0

func (wg *WaitGroup) IsDone() bool

IsDone returns true if there is pending work, and false otherwise.

func (*WaitGroup) Num added in v0.8.0

func (wg *WaitGroup) Num() int

Num returns the number of pending workers.

func (*WaitGroup) Wait added in v0.8.0

func (wg *WaitGroup) Wait(ctx context.Context)

Wait blocks until either the context is canceled or all items have completed.

Wait is pasable or usable as a fun.WaitFunc.

In many cases, callers should not rely on the Wait operation returning after the context expires: If Done() calls are used in situations that respect a context cancellation, aborting the Wait on a context cancellation, particularly when Wait gets a context that has the same lifecycle as the operations its waiting on, the result is that worker routines will leak. Nevertheless, in some situations, when workers may take a long time to respond to a context cancellation, being able to set a second deadline on Waiting may be useful.

Consider using `fun.WaitFunc(wg.Wait).Block()` if you want blocking semantics with the other features of this WaitGroup implementation.

type WorkerFunc added in v0.8.0

type WorkerFunc func(context.Context) error

WorkerFunc represents a basic function used in worker pools and other similar situations

func ObserveWorker added in v0.8.5

func ObserveWorker[T any](iter Iterator[T], fn Observer[T]) WorkerFunc

ObserveWorker has the same semantics as Observe, except that the operation is wrapped in a WaitFunc, and executed when the WaitFunc is called.

func (WorkerFunc) Add added in v0.9.3

func (wf WorkerFunc) Add(ctx context.Context, wg *WaitGroup, ob Observer[error])

Add runs the worker function in a go routine

func (WorkerFunc) Background added in v0.9.3

func (wf WorkerFunc) Background(ctx context.Context, ob Observer[error])

Background runs the worker function in a go routine and passes the output to the provided observer function.

func (WorkerFunc) Block added in v0.8.0

func (wf WorkerFunc) Block() error

Block executes the worker function with a context that will never expire and returns the error. Use with caution

func (WorkerFunc) MustWait added in v0.8.0

func (wf WorkerFunc) MustWait() WaitFunc

MustWait converts a Worker function into a wait function; however, if the worker produces an error MustWait converts the error into a panic.

func (WorkerFunc) Observe added in v0.8.0

func (wf WorkerFunc) Observe(ctx context.Context, ob Observer[error])

Observe runs the worker function, and observes the error (or nil response). Panics are converted to errors for both the worker function but not the observer function.

func (WorkerFunc) ObserveWait added in v0.8.0

func (wf WorkerFunc) ObserveWait(ob Observer[error]) WaitFunc

ObserveWait converts a worker function into a wait function, passing any error to the observer function. Only non-nil errors are observed.

func (WorkerFunc) Run added in v0.8.0

func (wf WorkerFunc) Run(ctx context.Context) error

Run is equivalent to calling the worker function directly, except the context passed to it is canceled when the worker function returns.

func (WorkerFunc) Safe added in v0.8.5

func (wf WorkerFunc) Safe(ctx context.Context) (err error)

Safe runs the worker function and converts the worker function to a panic to an error.

func (WorkerFunc) Signal added in v0.9.4

func (wf WorkerFunc) Signal(ctx context.Context) <-chan error

Signal runs the worker function in a background goroutine and returns the error in an error channel, that returns when the worker function returns. If Signal is called with a canceled context the worker is still executed (with that context.)

A value, possibly nil, is always sent through the channel, though the WorkerFunc runs in a different go routine, a panic handler will convert panics to errors.

func (WorkerFunc) WithTimeout added in v0.8.0

func (wf WorkerFunc) WithTimeout(timeout time.Duration) error

WithTimeout executes the worker function with the provided timeout using a new context.

Directories

Path Synopsis
Package adt provides "atomic data types" as strongly-typed generic helpers for simple atomic operations (including sync.Map, sync.Pool, and a typed value).
Package adt provides "atomic data types" as strongly-typed generic helpers for simple atomic operations (including sync.Map, sync.Pool, and a typed value).
Package assert provides an incredibly simple assertion framework, that relies on generics and simplicity.
Package assert provides an incredibly simple assertion framework, that relies on generics and simplicity.
check
GENERATED FILE FROM ASSERTION PACKAGE
GENERATED FILE FROM ASSERTION PACKAGE
Package erc provides a simple/fast error aggregation tool for collecting and aggregating errors.
Package erc provides a simple/fast error aggregation tool for collecting and aggregating errors.
Package itertool provides a set of functional helpers for managinging and using fun.Iterator implementations, including a parallel Map/Reduce, Merge, and other convenient tools.
Package itertool provides a set of functional helpers for managinging and using fun.Iterator implementations, including a parallel Map/Reduce, Merge, and other convenient tools.
Package pubsub provides a message broker for one-to-many or many-to-many message distribution.
Package pubsub provides a message broker for one-to-many or many-to-many message distribution.
Package risky contains a bunch of bad ideas for APIs and operations that will definitely lead to panics and deadlocks and incorrect behavior when used incorrectly.
Package risky contains a bunch of bad ideas for APIs and operations that will definitely lead to panics and deadlocks and incorrect behavior when used incorrectly.
Package seq provides single and double linked-list implementations and tools (e.g.
Package seq provides single and double linked-list implementations and tools (e.g.
Package Set provides ordered and unordered set implementations for arbitrary comparable types.
Package Set provides ordered and unordered set implementations for arbitrary comparable types.
Package srv provides a framework and toolkit for service orchestration.
Package srv provides a framework and toolkit for service orchestration.
Package testt (for test tools), provides a couple of useful helpers for common test patterns.
Package testt (for test tools), provides a couple of useful helpers for common test patterns.

Jump to

Keyboard shortcuts

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