Documentation ¶
Overview ¶
© 2020–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/) ISC License
Index ¶
- Constants
- Variables
- func ChannelSend[T any](ch chan<- T, value T, nonBlocking ...bool) (didSend, isNilChannel, isClosedChannel bool, err error)
- func Close(closable io.Closer, errp *error)
- func Closer[T any](ch chan T, errp *error)
- func CloserSend[T any](ch chan<- T, errp *error)
- func EndCallbacks(err error) (err2 error)
- func EnsureError(panicValue any) (err error)
- func ErrChWait(errCh <-chan error, errp *error)
- func Infallible(err error)
- func InvokeIf[T comparable](tp *T, fn func())
- func IsNil(v any) (isNil bool)
- func Log(format string, a ...any)
- func NilError(valueName string) (err error)
- func NoOnError(err error)
- func PanicToErr(errp *error, isPanic ...*bool)
- func Recover(deferredLocation func() DA, errp *error, onError OnError)
- func Recover2(deferredLocation func() DA, errp *error, onError OnError)
- func RecoverAnnotation(annotation string, errp *error, onError OnError)
- func RecoverErr(deferredLocation func() DA, errp *error, isPanic ...*bool)
- func SendErr(errCh chan<- error, errp *error)
- func Sprintf(format string, a ...interface{}) string
- func Uintptr(v any) (p uintptr)
- type AtomicMax
- type Awaitable
- type AwaitableCh
- type DA
- type OnError
Constants ¶
const ( Rfc3339s = "2006-01-02 15:04:05Z07:00" Rfc3339ms = "2006-01-02 15:04:05.000Z07:00" Rfc3339us = "2006-01-02 15:04:05.000000Z07:00" Rfc3339ns = "2006-01-02 15:04:05.000000000Z07:00" )
const SendNonBlocking = true
with nonBlocking set to SendNonBlocking, ChannelSend will never block
Variables ¶
var ErrEndCallbacks = EndCallbacks(errors.New("end callbacks error"))
ErrEndCallbacks indicates upon retun from a callback function that no more callbacks are desired. It does not indicate an error and is not returned as an error by any other function than the callback.
callback invocations may be thread-safe, re-entrant and panic-handling but this depends on the callback-invoking implementation used.
Usage:
if errors.Is(err, parl.ErrEndCallbacks) { …
var ErrNil = &nilValue{"value"}
ErrNil is used with errors.Is to detect that a panic or error value was caused by a value that cannot be nil, such as a function argument to a new function, was nil
- —
- a nilValue type implements:
- — a dummy NilValueError method
- — an Is method returning true for errors implementing a NilValueError method
Usage:
if errors.Is(err, parl.ErrNil) { …
Functions ¶
func ChannelSend ¶ added in v0.4.126
func ChannelSend[T any](ch chan<- T, value T, nonBlocking ...bool) (didSend, isNilChannel, isClosedChannel bool, err error)
ChannelSend is channel send without panics and possibly non-blocking
- if nonBlocking is SendNonBlocking or true, channel send will be attempted but not block
- didSend is true if value was successfully sent on ch
- err is non-nil if a panic occurred or ch is nil
- isNilChannel is true if the channel is nil, ie. send would block indefinitely
- isClosedChannel is true if the panic was caused by ch being closed
- there should be no panics other than from ch being closed
func Close ¶ added in v0.4.58
Close closes an io.Closer object.
- if errp is non-nil, panic values updates it using errors.AppendError.
- Close is thread-safe, panic-free and deferrable
- type Closer interface { Close() error }
func Closer ¶ added in v0.4.58
Closer is a deferrable function that closes a channel.
- if errp is non-nil, panic values updates it using errors.AppendError.
- Closer is thread-safe, panic-free and deferrable
func CloserSend ¶ added in v0.4.58
CloserSend is a deferrable function that closes a send-channel.
- if errp is non-nil, panic values updates it using errors.AppendError.
- CloserSend is thread-safe, panic-free and deferrable
func EndCallbacks ¶
func EnsureError ¶
ensureError interprets a panic values as an error
- returned value is either nil or an error value with stack trace
- the error is ensured to have stack trace
func ErrChWait ¶ added in v0.4.126
ErrChWait is a deferrable function receiving an error value on a channel
- used to wait for a goroutine
Usage:
var err error defer errorHandler(&err) var errCh = make(chan error, 1) go someFunc(errCh) defer parl.ErrChWait(errCh, &err) func someFunc(errCh chan<- error) { var err error defer parl.SendErr(errCh, &err) defer parl.PanicToErr(errp)
func Infallible ¶ added in v0.4.58
func Infallible(err error)
func InvokeIf ¶ added in v0.4.126
func InvokeIf[T comparable](tp *T, fn func())
InvokeIf is a deferrable function invoking its function argument when:
- the pointer tp is non-nil and the function fn is non-nil
- what tp points to is not a T zero-value
Usage:
someFlag := false defer InvokeIf(&someFlag, someFunction) … someFlag = someValue
func IsNil ¶ added in v0.4.135
IsNil checks whether an interface value is truly nil
- In Go, comparison of an interface value that has been assigned a concretely typed nil value yields unexpected results
- (any)((*int)(nil)) == nil → false, where true is expected
- IsNil((*int)(nil)) → true
- as of go1.20.3, an interface value is 2 pointers,
- — the first currently assigned type and
- —the second currently assigned value
func NilError ¶ added in v0.4.126
NilError returns an error used with panic() indicating that a value that cannot be nil, such as a function argument to a new function, was nil
- such panics typically indicate compile-time issues with code
Usage:
func NewX(xValue *int) (x *X) { if xValue == nil { panic(parl.NilError("xValue")) // “somePackage.NewX xValue cannot be nil”
func NoOnError ¶
func NoOnError(err error)
NoOnError is used with Recover and Recover2 to silence the default error logging
func PanicToErr ¶ added in v0.4.125
PanicToErr recovers active panic, aggregating errors in errp
- PanicToErr does not provide enclosing function. For that, use RecoverErr: “recover from panic in pack.Func…”
- errp cannot be nil
- if isPanic is non-nil and active panic, it is set to true
sample error message, including message in the panic value and the code line causing the panic:
recover from panic: message: “runtime error: invalid memory address or nil pointer dereference” at parl.panicFunction()-panic-to-err_test.go:96
Usage:
func someFunc() (isPanic bool, err error) { defer parl.PanicToErr(&err, &isPanic) func someGoroutine(g parl.Go) { var err error defer g.Register().Done(&err) defer parl.PanicToErr(&err)
func Recover ¶
Recover recovers panic using deferred annotation
- onError error receiver is invoked exactly one
- errors in *errp and panic are aggregated into a single error value
- if onError non-nil, the function is invoked once with the aggregate error
- if onError nil, the aggregate error is logged to standard error
- if onError is [Parl.NoOnErrror], logging is suppressed
- if errp is non-nil, it is updated with the aggregate error
Usage:
func someFunc() (err error) { defer parl.Recover(func() parl.DA { return parl.A() }, &err, parl.NoOnError)
func Recover2 ¶
Recover2 recovers panic using deferred annotation
- if onError non-nil, the function is invoked with any error in *errp and any panic
- if onError nil, the errors are logged to standard error
- if onError is [Parl.NoOnErrror], logging is suppressed
- if errp is non-nil, it is updated with an aggregate error
Usage:
func someFunc() (err error) { defer parl.Recover2(func() parl.DA { return parl.A() }, &err, parl.NoOnError)
func RecoverAnnotation ¶ added in v0.4.135
RecoverAnnotation is like Recover but with fixed-string annotation
func RecoverErr ¶ added in v0.4.117
RecoverErr recovers panic using deferred annotation
- signature is error pointer and a possible isPanic pointer
Usage:
func someFunc() (isPanic bool, err error) { defer parl.RecoverErr(func() parl.DA { return parl.A() }, &err, &isPanic)
func SendErr ¶ added in v0.4.126
SendErr sends error as the final action of a goroutine
- SendErr should only panic from structural coding problems
func Uintptr ¶ added in v0.4.125
Uintptr returns v as a pointer
- usable with fmt.Printf %x
- if uintptr is not used, Printf may go off interpreting the value pointed to, depending on its type
Usage:
var p = &SomeStruct{} parl.Log("p: 0x%x", parl.Uintptr(p))
Types ¶
type AtomicMax ¶
type AtomicMax[T constraints.Integer] struct { // contains filtered or unexported fields }
func NewAtomicMax ¶
func NewAtomicMax[T constraints.Integer](value T) (atomicMax *AtomicMax[T])
type Awaitable ¶ added in v0.4.126
type Awaitable struct {
// contains filtered or unexported fields
}
Awaitable is a semaphore allowing any number of threads to observe and await an event
- one-to-many, happens-before
- the synchronization mechanic is closing channel, allowing consumers to await multiple events
- IsClosed provides thread-safe observability
- Close is idempotent, thread-safe, deferrable and panic-free
- [parl.CyclicAwaitable] is re-armable, cyclic version
- —
- alternative low-blocking inter-thread mechanics are sync.WaitGroup and sync.RWMutex but those are less performant for the managing thread
func NewAwaitable ¶ added in v0.4.126
func NewAwaitable() (awaitable *Awaitable)
NewAwaitable returns a one-to-many sempahore
func (*Awaitable) Ch ¶ added in v0.4.126
func (a *Awaitable) Ch() (ch AwaitableCh)
Ch returns an awaitable channel. Thread-safe
type AwaitableCh ¶ added in v0.4.126
type AwaitableCh <-chan struct{}
AwaitableCh is a one-to-many inter-thread wait-mechanic with happens-before
- AwaitableCh implements a semaphore
- implementation is a channel whose only allowed operation is channel receive
- AwaitableCh transfers no data, instead channel close is the significant event
Usage:
<-ch // waits for event select { case <-ch: hasHappened = true default: hasHappened = false }
type DA ¶ added in v0.4.117
type DA *pruntime.CodeLocation
DA is the value returned by a deferred code location function