Documentation
¶
Overview ¶
Package gock (a portmanteau of the "go" statement and "block") provides structured concurrency [1] utilities for Go.
[1] https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AddConcurrentError ¶
AddConcurrentError merges two concurrent, possibly nil errors.
If both are nil, nil is returned.
If both are equal, ie. the same error value has been passed twice, that error is returned.
If only one of the two is non-nil, that one is returned.
If both are non-nil, a ConcurrentErrors is returned with both. If any of them is itself a ConcurrentErrors, the resulting ConcurrentErrors is flattened, ie. it incorporates the errors contained in the merged ConcurrentErrors, not the ConcurrentErrors themselves.
func AnyIs ¶
AnyIs returns whether any of the concurrent errors bundlded in err is the given error, as defined by errors.Is.
func Wait ¶
Wait runs the provided functions concurrently. It waits for all of them to return before returning itself.
It returns the result of repeatedly calling AddConcurrentError on each error returned by the function.
If any of the functions panics in another goroutine, the recovered value is repanicked in the goroutine that calls Wait, wrapped in an error type that keeps the original stack trace where the panic happened and that has the method Unwrap() error to recover the original value, if it was an error.
Example (CommonErrorAncestor) ¶
package main
import (
"errors"
"fmt"
"github.com/tcard/gock"
)
func main() {
var ErrCommonAncestor = errors.New("ye eldest")
err := gock.Wait(func() error {
return fmt.Errorf(
"first in first chain: %w",
fmt.Errorf(
"second in first chain: %w",
ErrCommonAncestor,
),
)
}, func() error {
return nil
}, func() error {
return fmt.Errorf(
"first in second chain: %w",
ErrCommonAncestor,
)
})
fmt.Println(errors.Is(err, ErrCommonAncestor))
}
Output: true
Example (ConcurrentErrors) ¶
package main
import (
"errors"
"fmt"
"github.com/tcard/gock"
)
func main() {
var ErrOops = errors.New("oops")
var ErrFailed = errors.New("failed")
err := gock.Wait(func() error {
return ErrFailed
}, func() error {
return ErrOops
})
fmt.Println(gock.AnyIs(err, ErrOops))
fmt.Println(gock.AnyIs(err, ErrFailed))
}
Output: true true
Example (SameErrorTwice) ¶
package main
import (
"errors"
"fmt"
"github.com/tcard/gock"
)
func main() {
var ErrOops = errors.New("oops")
err := gock.Wait(func() error {
return ErrOops
}, func() error {
return nil
}, func() error {
return ErrOops
})
fmt.Println(err == ErrOops)
}
Output: true
Example (SingleError) ¶
package main
import (
"errors"
"fmt"
"github.com/tcard/gock"
)
func main() {
var ErrOops = errors.New("oops")
err := gock.Wait(func() error {
return nil
}, func() error {
return ErrOops
})
fmt.Println(err == ErrOops)
}
Output: true
Types ¶
type ConcurrentErrors ¶
type ConcurrentErrors struct {
Errors []error
}
ConcurrentErrors aggregates multiple errors that happened concurrently but were then aggreegated with AddConcurrentError.
Its Unwrap method returns, if it exists, the common ancestor among the chains of all errors.
Use AddConcurrentError to construct it, which keeps the invariant that a ConcurrentErrors doesn't contain other ConcurrentErrors.
func (ConcurrentErrors) Error ¶
func (errs ConcurrentErrors) Error() string
Error implements error for ConcurrentErrors.
func (ConcurrentErrors) Is ¶ added in v0.1.6
func (errs ConcurrentErrors) Is(err error) bool
Is returns true if errors.Is(subError, err) returns true for all errors inside the ConcurrentErrors.
func (ConcurrentErrors) Unwrap ¶
func (errs ConcurrentErrors) Unwrap() error
Unwrap returns, if it exists, the common ancestor among the error chains of all errors contained in the ConcurrentErrors.
type GoFunc ¶ added in v0.1.4
type GoFunc func(func() error)
A GoFunc runs a given function concurrently.
func Bundle ¶
Bundle returns a function g to run functions concurrently, and a function wait to wait for all the functions provided to g to return before returning itself. Thus, the provided functions run in a "bundle" of concurrent goroutines.
wait returns the result of repeatedly calling AddConcurrentError on each error returned by the function.
It is safe to call g or wait concurrently from different goroutines.
Once wait returns, calling g again panics. Calling wait more than once just returns the same result.
If any of the functions panics in another goroutine, the recovered value is repanicked in the goroutine that calls wait, wrapped in an error type that keeps the original stack trace where the panic happened and that has the method Unwrap() error to recover the original value, if it was an error.
You may prefer Wait, which is a shortcut.