cyclebreaker

package
v0.4.165 Latest Latest
Warning

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

Go to latest
Published: Apr 30, 2024 License: ISC Imports: 15 Imported by: 0

Documentation

Overview

© 2020–present Harald Rudell <harald.rudell@gmail.com> (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 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. 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) { …
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) { …

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 EndCallbacks

func EndCallbacks(err error) (err2 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 ErrChWait added in v0.4.126

func ErrChWait(errCh <-chan error, errp *error)

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

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

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, onError OnError)

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

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, onError OnError)

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

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, errp *error, onError OnError)

RecoverAnnotation is like Recover but with fixed-string annotation

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

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

func SendErr(errCh chan<- error, errp *error)

SendErr sends error as the final action of a goroutine

  • SendErr should only panic from structural coding problems

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 AtomicMax

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

func NewAtomicMax

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

func (*AtomicMax[T]) Max

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

func (*AtomicMax[T]) Max1

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

func (*AtomicMax[T]) Value

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

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

func (*Awaitable) Close added in v0.4.126

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

Close triggers awaitable by closing the channel

  • upon return, the channel is guaranteed to be closed
  • 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

  • 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 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

var NoOnError OnError

nil OnError function

  • public for RecoverAnnotation

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