cyclebreaker

package
v0.4.182 Latest Latest
Warning

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

Go to latest
Published: Jun 3, 2024 License: ISC Imports: 16 Imported by: 0

Documentation

Overview

© 2020–present Harald Rudell <[email protected]> (https://haraldrudell.github.io/haraldrudell/) ISC License

Index

Constants

View Source
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"
)
View Source
const EvCon = true

Awaitable.Close argument to Close meaning eventually consistency

  • may return before the channel is actually closed
View Source
const SendNonBlocking = true

with nonBlocking set to SendNonBlocking, ChannelSend will never block

Variables

View Source
var ErrEndCallbacks = EndCallbacks(errors.New("end callbacks error"))

ErrEndCallbacks indicates upon retun from a callback function that no more callbacks are desired

  • ErrEndCallbacks does not indicate an error and should not be returned by any other function than a callback
  • check for ErrrEndCallback is using the errors.Is method with the [parl.ErrEndCallbacks] value
  • EndCallbacks creates an ErrEndCallbacks value basd on another error
  • an ErrEndCallbacks type implements:
  • — an Is method returning true for errors implementing a EndCallbacks method
  • parl.ErrEndCallbacks additionally implements:
  • — a dummy EndCallbacks method

Usage:

func callback() (err error) {
  return parl.ErrEndCallbacks

  if errors.Is(err, parl.ErrEndCallbacks) {
    err = nil
    …
View Source
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) { …
View Source
var NoErrp *error

argument to Recover: no error aggregation

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

func Close(closable io.Closer, errp *error)

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

func Closer[T any](ch chan T, errp *error)

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

func CloserSend[T any](ch chan<- T, errp *error)

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 DeferredErrorSink added in v0.4.178

func DeferredErrorSink(errorSink ErrorSink, errp *error)

DeferredErrorSink is a deferrable function that provides an error to ErrorSink if errp is non-nil pointer to non-nil error

func EndCallbacks

func EndCallbacks(err error) (err2 error)

EndCallbacks creates a EndCallbacks error based on another error

func EnsureError

func EnsureError(panicValue any) (err error)

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 IsNil added in v0.4.135

func IsNil(v any) (isNil bool)

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 Log

func Log(format string, a ...any)

func NilError added in v0.4.126

func NilError(valueName string) (err error)

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 PanicToErr added in v0.4.125

func PanicToErr(errp *error, isPanic ...*bool)

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”
  • parl recover options:
  • RecoverErr: aggregates to error pointer with enclosing function location, optional panic flag
  • Recover: aggregates to error pointer with enclosing function location, optional single-invocation [parl.ErrorSink]
  • Recover2: aggregates to error pointer with enclosing function location, optional multiple-invocation [parl.ErrorSink]
  • RecoverAnnotation: aggregates to error pointer with fixed-string annotation, optional single-invocation [parl.ErrorSink]
  • PanicToErr: aggregates to error pointer with generic annotation, optional panic flag
  • — preferrably: RecoverErr, Recover or Recover2 should be used to provide the package and function name of the enclosing function for the defer-statement that invoked recover
  • — PanicToErr and RecoverAnnotation cannot provide where in the stack trace recover was invoked

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

func Recover(deferredLocation func() DA, errp *error, errorSink ...ErrorSink1)

Recover recovers panic using deferred annotation

  • Recover creates a single aggregate error of *errp and any panic
  • if onError non-nil, the function is invoked zero or one time with the aggregate error
  • if onError nil, the error is logged to standard error
  • if errp is non-nil, it is updated with any aggregate error
  • parl recover options:
  • RecoverErr: aggregates to error pointer with enclosing function location, optional panic flag
  • Recover: aggregates to error pointer with enclosing function location, optional single-invocation [parl.ErrorSink]
  • Recover2: aggregates to error pointer with enclosing function location, optional multiple-invocation [parl.ErrorSink]
  • RecoverAnnotation: aggregates to error pointer with fixed-string annotation, optional single-invocation [parl.ErrorSink]
  • PanicToErr: aggregates to error pointer with generic annotation, optional panic flag
  • — preferrably: RecoverErr, Recover or Recover2 should be used to provide the package and function name of the enclosing function for the defer-statement that invoked recover
  • — PanicToErr and RecoverAnnotation cannot provide where in the stack trace recover was invoked

Usage:

func someFunc() (err error) {
  defer parl.Recover(func() parl.DA { return parl.A() }, &err, parl.NoOnError)

func Recover2

func Recover2(deferredLocation func() DA, errp *error, errorSink ...ErrorSink1)

Recover2 recovers panic using deferred annotation

  • if onError non-nil, the function is invoked zero, one or two times with any error in *errp and any panic
  • if onError nil, errors are logged to standard error
  • if errp is non-nil:
  • — if *errp was nil, it is updated with any panic
  • — if *errp was non-nil, it is updated with any panic as an aggregate error
  • parl recover options:
  • RecoverErr: aggregates to error pointer with enclosing function location, optional panic flag
  • Recover: aggregates to error pointer with enclosing function location, optional single-invocation [parl.ErrorSink]
  • Recover2: aggregates to error pointer with enclosing function location, optional multiple-invocation [parl.ErrorSink]
  • RecoverAnnotation: aggregates to error pointer with fixed-string annotation, optional single-invocation [parl.ErrorSink]
  • PanicToErr: aggregates to error pointer with generic annotation, optional panic flag
  • — preferrably: RecoverErr, Recover or Recover2 should be used to provide the package and function name of the enclosing function for the defer-statement that invoked recover
  • — PanicToErr and RecoverAnnotation cannot provide where in the stack trace recover was invoked

Usage:

func someFunc() (err error) {
  defer parl.Recover2(func() parl.DA { return parl.A() }, &err, parl.NoOnError)

func RecoverAnnotation added in v0.4.135

func RecoverAnnotation(annotation string, deferredLocation func() DA, errp *error, errorSink ...ErrorSink1)

RecoverAnnotation is like Recover but with fixed-string annotation

  • default annotation: “recover from panic:”
  • parl recover options:
  • RecoverErr: aggregates to error pointer with enclosing function location, optional panic flag
  • Recover: aggregates to error pointer with enclosing function location, optional single-invocation [parl.ErrorSink]
  • Recover2: aggregates to error pointer with enclosing function location, optional multiple-invocation [parl.ErrorSink]
  • RecoverAnnotation: aggregates to error pointer with fixed-string annotation, optional single-invocation [parl.ErrorSink]
  • PanicToErr: aggregates to error pointer with generic annotation, optional panic flag
  • — preferrably: RecoverErr, Recover or Recover2 should be used to provide the package and function name of the enclosing function for the defer-statement that invoked recover
  • — PanicToErr and RecoverAnnotation cannot provide where in the stack trace recover was invoked

Usage:

func someFunc() (err error) {
  defer parl.RecoverAnnotation("property " + property, func() parl.DA { return parl.A() }, &err, parl.NoOnError)

func RecoverErr added in v0.4.117

func RecoverErr(deferredLocation func() DA, errp *error, isPanic ...*bool)

RecoverErr recovers panic using deferred annotation

  • signature is error pointer and a possible isPanic pointer
  • parl recover options:
  • RecoverErr: aggregates to error pointer with enclosing function location, optional panic flag
  • Recover: aggregates to error pointer with enclosing function location, optional single-invocation [parl.ErrorSink]
  • Recover2: aggregates to error pointer with enclosing function location, optional multiple-invocation [parl.ErrorSink]
  • RecoverAnnotation: aggregates to error pointer with fixed-string annotation, optional single-invocation [parl.ErrorSink]
  • PanicToErr: aggregates to error pointer with generic annotation, optional panic flag
  • — preferrably: RecoverErr, Recover or Recover2 should be used to provide the package and function name of the enclosing function for the defer-statement that invoked recover
  • — PanicToErr and RecoverAnnotation cannot provide where in the stack trace recover was invoked

Usage:

func someFunc() (isPanic bool, err error) {
  defer parl.RecoverErr(func() parl.DA { return parl.A() }, &err, &isPanic)

func Sprintf

func Sprintf(format string, a ...interface{}) string

Sprintf is a printer that supports comma in large numbers

func Uintptr added in v0.4.125

func Uintptr(v any) (p uintptr)

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 AddError deprecated added in v0.4.178

type AddError func(err error)

AddError is a function to submit non-fatal errors

Deprecated: should use github.com/haraldrudell/parl.ErrorSink possibly the error container github.com/haraldrudell/parl.ErrSlice

var NoAddErr AddError

absent [parl.AddError] argument

Deprecated: should use github.com/haraldrudell/parl.ErrorSink possibly the error container github.com/haraldrudell/parl.ErrSlice

type Atomic32 added in v0.4.178

type Atomic32[T uint32Types] struct {
	// contains filtered or unexported fields
}

Atomic32 is a generic 32-bit integer with atomic access

  • generic for named types of select signed and unsigned underlying integers
  • generic for select built-in integer types
  • includes ~int ~uint
  • excludes ~uint64 ~uintptr ~int64
  • for large values or excluded types, use [Atomic64]
  • generic version of atomic.Uint32
  • when using int or uint underlying type on a 64-bit platform, type-conversion data loss may occur for larger than 32-bit values
  • no performance impact compared to other atomics

func (*Atomic32[T]) Add added in v0.4.178

func (a *Atomic32[T]) Add(delta T) (new T)

Add atomically adds delta to a and returns the new value.

func (*Atomic32[T]) CompareAndSwap added in v0.4.178

func (a *Atomic32[T]) CompareAndSwap(old, new T) (swapped bool)

CompareAndSwap executes the compare-and-swap operation for a.

func (*Atomic32[T]) Load added in v0.4.178

func (a *Atomic32[T]) Load() (value T)

Load atomically loads and returns the value stored in a.

func (*Atomic32[T]) Store added in v0.4.178

func (a *Atomic32[T]) Store(val T)

Store atomically stores val into a.

func (*Atomic32[T]) Swap added in v0.4.178

func (a *Atomic32[T]) Swap(new T) (old T)

Swap atomically stores new into a and returns the previous value.

type AtomicError added in v0.4.178

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

func (*AtomicError) AddError added in v0.4.178

func (a *AtomicError) AddError(err error)

func (*AtomicError) Error added in v0.4.178

func (a *AtomicError) Error() (err error, hasValue bool)

type AtomicMax

type AtomicMax[T constraints.Integer] struct {
	// contains filtered or unexported fields
}

AtomicMax is a thread-safe max container

  • hasValue indicator true if a value was equal to or greater than threshold
  • optional threshold for minimum accepted max value
  • generic for any basic or named Integer type
  • negative values cause panic
  • can used to track maximum time.Duration that should never be negative
  • if threshold is not used, initialization-free
  • wait-free CompareAndSwap mechanic

func NewAtomicMax

func NewAtomicMax[T constraints.Integer](threshold T) (atomicMax *AtomicMax[T])

NewAtomicMax returns a thread-safe max container

  • T any basic or named type with underlying type integer
  • negative values not allowed and cause panic
  • if threshold is not used, AtomicMax is initialization-free

func (*AtomicMax[T]) Max

func (m *AtomicMax[T]) Max() (value T, hasValue bool)

Max returns current max and value-present flag

  • hasValue true indicates that value reflects a Value invocation
  • hasValue false: value is zero-value
  • Thread-safe

func (*AtomicMax[T]) Max1

func (m *AtomicMax[T]) Max1() (value T)

Max1 returns current maximum whether zero-value or set by Value

  • threshold is ignored
  • Thread-safe

func (*AtomicMax[T]) Value

func (m *AtomicMax[T]) Value(value T) (isNewMax bool)

Value updates the container with a possible max value

  • value cannot be negative, that is panic
  • isNewMax is true if:
  • — value is equal to or greater than any threshold and
  • — invocation recorded the first 0 or
  • — a new max
  • upon return, Max and Max1 are guaranteed to reflect the invocation
  • the return order of concurrent Value invocations is not guaranteed
  • Thread-safe

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 any number of events in parallel

  • Awaitable.Ch returns an awaitable channel closing on trig of awaitable. The initial channel state is open
  • Awaitable.Close triggers the awaitable, ie. closes the channel. Upon return, the channel is guaranteed to be closed
  • — with optional EvCon argument, Close is eventually consistent, ie. Close may return prior to channel actually closed for higher performance
  • Awaitable.IsClosed returns whether the awaitable is triggered, ie. if the channel is closed
  • initialization-free, one-to-many wait mechanic, synchronizes-before, observable
  • use of channel as mechanic allows consumers to await multiple events
  • Awaitable costs a lazy channel and pointer allocation
  • note: [parl.CyclicAwaitable] is re-armable, cyclic version
  • alternative low-blocking inter-thread mechanics are sync.WaitGroup and sync.RWMutex
  • — neither is observable and the consumer cannot await other events in parallel
  • — RWMutex cyclic use has inversion of control issues
  • — WaitGroup lacks control over waiting threads requiring cyclic use to employ a re-created pointer and value
  • — both are less performant for the managing thread

func (*Awaitable) Ch added in v0.4.126

func (a *Awaitable) Ch() (ch AwaitableCh)

Ch returns an awaitable channel. Thread-safe

func (*Awaitable) Close added in v0.4.126

func (a *Awaitable) Close(eventuallyConsistent ...bool) (didClose bool)

Close triggers awaitable by closing the channel

  • upon return, the channel is guaranteed to be closed
  • eventuallyConsistent EvCon: may return before the channel is atcually closed for higher performance
  • idempotent, deferrable, panic-free, thread-safe

func (*Awaitable) IsClosed added in v0.4.126

func (a *Awaitable) IsClosed() (isClosed bool)

isClosed inspects whether the awaitable has been triggered

  • on true return, it is guaranteed that the channel has been closed
  • 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

DA is the value returned by a deferred code location function

func A added in v0.4.117

func A() DA

A is a thunk returning a deferred code location

type ErrorSink added in v0.4.178

type ErrorSink interface {
	// AddError is a function to submit non-fatal errors
	//	- triggers [ErrorSource.WaitCh]
	//	- values are received by [ErrorSource.Error] or [ErrorsSource.Errors]
	AddError(err error)
	// EndErrors optionally indicates that no more AddError
	// invocations will occur
	//	- enables triggering of [ErrorSource.EndCh]
	EndErrors()
}

ErrorSink provides send of non-fatal errors one at a time

func NewErrorSinkEndable added in v0.4.178

func NewErrorSinkEndable(errorSink1 ErrorSink1) (errorSink ErrorSink)

NewErrorSinkEndable returns an error sink based on a type with private addError method

type ErrorSink1 added in v0.4.178

type ErrorSink1 interface {
	// AddError is a function to submit non-fatal errors
	//	- triggers [ErrorSource.WaitCh]
	//	- values are received by [ErrorSource.Error] or [ErrorsSource.Errors]
	AddError(err error)
}

ErrorSink1 provides send of non-fatal errors one at a time that cannot be closed

var Infallible ErrorSink1 = &infallible{}

Infallible is an error sink logging to standard error

  • intended for failure recovery of threads that should not fail
  • use should be limited to threads reading from sockets that cannot be terminated, ie. standard input or the udev netlink socket
  • outputs the error with stack trace and the stack trace invoking [Infallible.AddError]

type ErrorSource added in v0.4.178

type ErrorSource interface {
	ErrorSource1
	// WaitCh waits for the next error, possibly indefinitely
	//	- each invocation returns a channel that closes on errors available
	//	- — invocations may return different channel values
	//	- the next invocation may return a different channel object
	WaitCh() (ch AwaitableCh)
	// EndCh awaits the error source closing:
	//	- the error source must be read to empty
	//	- the error source must be closed by the error-source providing entity
	EndCh() (ch AwaitableCh)
}

ErrorSource provides receive of errors one at a time

type ErrorSource1 added in v0.4.178

type ErrorSource1 interface {
	// Error returns the next error value
	//	- hasValue true: err is valid
	//	- hasValue false: the error source is currently empty
	Error() (err error, hasValue bool)
}

ErrorSource1 is an error source that is not awaitable

type ErrorsSource added in v0.4.178

type ErrorsSource interface {
	// Errors returns a slice of errors or nil
	Errors() (errs []error)
}

ErrorsSource provides receiving multiple errors at once

type Errs added in v0.4.178

type Errs interface {
	// ErrorSource provides receive of errors one at a time using
	// WaitCh Error
	ErrorSource
	// Errors returns a slice of errors
	ErrorsSource
}

Errs provides receiving errors, one at a time or multiple

type OnError added in v0.4.117

type OnError func(err error)

OnError is a function that receives error values from an errp error pointer or a panic

deprecated: use ErrorSink

var NoOnError OnError

nil OnError function

  • public for RecoverAnnotation

deprecated: use ErrorSink

type OnErrorStrategy added in v0.4.154

type OnErrorStrategy uint8

how OnError is handled: recoverOnErrrorOnce recoverOnErrrorMultiple recoverOnErrrorNone

Jump to

Keyboard shortcuts

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