Documentation ¶
Overview ¶
Package g0 provides Go threads and thread-groups
Index ¶
- Constants
- Variables
- func NewGoError(err error, errContext parl.GoErrorContext, g0 parl.Go) (goError parl.GoError)
- func NewGoGroup(ctx context.Context, onFirstFatal ...parl.GoFatalCallback) (g0 parl.GoGroup)
- func Reader(shouldTerminate *atomic.Bool, addError parl.AddError, log parl.PrintfFunc, ...)
- func Shorts(threads []parl.ThreadData) (s string)
- type Go
- func (g *Go) AddError(err error)
- func (g *Go) Creator() (threadID parl.ThreadID, createLocation *pruntime.CodeLocation)
- func (g *Go) Done(errp *error)
- func (i *Go) EntityID() (id parl.GoEntityID)
- func (g *Go) Go() (g00 parl.Go)
- func (g *Go) GoID() (threadID parl.ThreadID)
- func (g *Go) GoRoutine() (threadID parl.ThreadID, goFunction *pruntime.CodeLocation)
- func (g *Go) Register(label ...string) (g00 parl.Go)
- func (g *Go) String() (s string)
- func (g *Go) SubGo(onFirstFatal ...parl.GoFatalCallback) (subGo parl.SubGo)
- func (g *Go) SubGroup(onFirstFatal ...parl.GoFatalCallback) (subGroup parl.SubGroup)
- func (g *Go) ThreadInfo() (threadData parl.ThreadData)
- func (g *Go) Wait()
- func (g *Go) WaitCh() (ch parl.AwaitableCh)
- type GoError
- func (e *GoError) Err() (err error)
- func (e *GoError) ErrContext() (errContext parl.GoErrorContext)
- func (e *GoError) ErrString() (errString string)
- func (e *GoError) Error() (message string)
- func (e *GoError) Go() (g0 parl.Go)
- func (e *GoError) IsFatal() (isThreadExit bool)
- func (e *GoError) IsThreadExit() (isThreadExit bool)
- func (e *GoError) String() (s string)
- func (e *GoError) Time() (when time.Time)
- type GoGroup
- func (g *GoGroup) Add(goEntityID parl.GoEntityID, threadData *ThreadData)
- func (g *GoGroup) Cancel()
- func (g *GoGroup) CascadeEnableTermination(delta int)
- func (g *GoGroup) Ch() (ch <-chan parl.GoError)
- func (g *GoGroup) ConsumeError(goError parl.GoError)
- func (c *GoGroup) Context() (ctx context.Context)
- func (g *GoGroup) EnableTermination(allowTermination ...bool) (mayTerminate bool)
- func (g *GoGroup) FirstFatal() (firstFatal *parl.OnceWaiterRO)
- func (g *GoGroup) FromGoGo() (g2 parl.Go)
- func (g *GoGroup) FromGoSubGo(onFirstFatal ...parl.GoFatalCallback) (g1 parl.SubGo)
- func (g *GoGroup) FromGoSubGroup(onFirstFatal ...parl.GoFatalCallback) (g2 parl.SubGroup)
- func (g *GoGroup) Go() (g2 parl.Go)
- func (g *GoGroup) GoDone(thread parl.Go, err error)
- func (g *GoGroup) Internals() (isEnd func() bool, isAggregateThreads *atomic.Bool, ...)
- func (g *GoGroup) NamedThreads() (threads []parl.ThreadData)
- func (g *GoGroup) SetDebug(debug parl.GoDebug, log ...parl.PrintfFunc)
- func (g *GoGroup) String() (s string)
- func (g *GoGroup) SubGo(onFirstFatal ...parl.GoFatalCallback) (g2 parl.SubGo)
- func (g *GoGroup) SubGroup(onFirstFatal ...parl.GoFatalCallback) (g2 parl.SubGroup)
- func (g *GoGroup) Threads() (threads []parl.ThreadData)
- func (g *GoGroup) ThreadsInternal() (m parli.ThreadSafeMap[parl.GoEntityID, *ThreadData])
- func (g *GoGroup) UpdateThread(goEntityID parl.GoEntityID, threadData *ThreadData)
- func (g *GoGroup) Wait()
- func (g *GoGroup) WaitCh() (ch parl.AwaitableCh)
- type ThreadData
- func (t *ThreadData) Create() (createLocation *pruntime.CodeLocation)
- func (t *ThreadData) Func() (funcLocation *pruntime.CodeLocation)
- func (t *ThreadData) Get() (threadID parl.ThreadID, createLocation pruntime.CodeLocation, ...)
- func (t *ThreadData) LabeledString() (s string)
- func (t *ThreadData) Name() (label string)
- func (t *ThreadData) SetCreator(cl *pruntime.CodeLocation)
- func (t *ThreadData) Short() (s string)
- func (t *ThreadData) String() (s string)
- func (t *ThreadData) ThreadID() (threadID parl.ThreadID)
- func (t *ThreadData) Update(threadID parl.ThreadID, createInvocation, goFunction *pruntime.CodeLocation, ...)
- type ThreadSafeThreadData
- func (tw *ThreadSafeThreadData) Get() (thread *ThreadData)
- func (tw *ThreadSafeThreadData) HaveThreadID() (haveThreadID bool)
- func (tw *ThreadSafeThreadData) SetCreator(cl *pruntime.CodeLocation)
- func (tw *ThreadSafeThreadData) ThreadID() (threadID parl.ThreadID)
- func (tw *ThreadSafeThreadData) Update(threadID parl.ThreadID, createInvocation *pruntime.CodeLocation, ...)
Constants ¶
const ( ThreadDataEmpty = "[empty]" ThreadDataNil = "threadData:nil" )
Variables ¶
var GoGroupFactory parl.GoFactory = &goGroupFactory{}
var NoAddErr parl.AddError
for Reader
var NoLog parl.PrintfFunc
for Reader
var NoShouldTerm *atomic.Bool
for Reader
Functions ¶
func NewGoError ¶
NewGoError creates a GoError based on an error
func NewGoGroup ¶ added in v0.4.19
NewGoGroup returns a stand-alone thread-group with its own error channel. Thread-safe.
- ctx is not canceled by the thread-group
- ctx may initiate thread-group Cancel
- a stand-alone GoGroup thread-group has goGroupParent nil
- non-fatal and fatal errors from the thread-group’s threads are sent on the GoGroup’s error channel
- the GoGroup processes Go invocations and thread-exits from its own threads and the threads of its subordinate thread-groups wait-group and that of its parent
- cancel of the GoGroup’s context signals termination to its own threads and all threads of its subordinate thread-groups
- the GoGroup’s context is canceled when its provided parent context is canceled or any of its threads invoke the GoGroup’s Cancel method
- the GoGroup terminates when its error channel closes from all threads in its own thread-group and that of any subordinate thread-groups have exited.
func Reader ¶ added in v0.4.147
func Reader(shouldTerminate *atomic.Bool, addError parl.AddError, log parl.PrintfFunc, goGroup parl.GoGroup, g parl.GoResult)
Reader thread reads the error channel of a GoGroup or [SubGroup]
- shouldTerminate is an optional pointer that an application’s most important goroutine sets to true prior to exit, causing graceful shutdown
- addError receives fatal thread-exits. If not present, those are logged. typically github.com/haraldrudell/parl/mains.Executable.AddErr
- log outputs warnings and more, default parl.Log standard error
- g is from parl.NewGoResult or parl.NewGoResult2 making Reader awaitable
- a GoGroup’s or SubGroup’s error channel is unbound buffer so Reader is only required for:
- — real-time warning output
- — terminating the process while additional goroutines are still running:
- — on fatal thread exit or
- — on exit of a primary goroutine
- —
- because reading of the threadgroup’s error channel must not stop, it is done in this separate thread.
- reading continues until:
- — the threadGroup context is canceled by eg. GoGroup.Cancel
- — the last thread exits
- — a thread exits with error
- — on thread exit, shouldTerminate is true
Usage:
func main() { var err error defer mains.MinimalRecovery(&err) var goGroup = g0.NewGoGroup(context.Background()) defer goGroup.Wait() var goResult = parl.NewGoResult() defer goResult.ReceiveError(&err) go g0.Reader(g0.NoSholdTerm, g0.NoAddErr, g0.NoLog, goGroup, goResult) defer goGroup.Cancel() go someGoroutine(goGroup.Go())
func Shorts ¶ added in v0.4.43
func Shorts(threads []parl.ThreadData) (s string)
Shorts retruns a string of Short descriptions of all threads in the slice
- string is never empty
Types ¶
type Go ¶ added in v0.4.21
type Go struct {
// contains filtered or unexported fields
}
Go supports a goroutine executing part of a thread-group. Thread-safe.
- Register allows to name the thread and collects information on the new thread
- AddError processes non-fatal errors
- Done handles thread termination and fatal errors and is deferrable. The Go thread terminates on Done invocation.
- Go creates a sibling thread object to be provided in a go statement
- SubGo creates a subordinate thread-group managed by the parent thread group. The SubGo can be independently terminated or terminated prior to thread exit.
- SubGroup creates a subordinate thread-group with its own error channel. Fatal-error thread-exits in SubGroup can be recovered locally in that thread-group
func (*Go) Creator ¶ added in v0.4.92
func (g *Go) Creator() (threadID parl.ThreadID, createLocation *pruntime.CodeLocation)
func (*Go) Done ¶ added in v0.4.21
Done handles thread exit. Deferrable
- *errp contains possible fatalk thread error
- errp can be nil
func (*Go) EntityID ¶ added in v0.4.117
func (i *Go) EntityID() (id parl.GoEntityID)
EntityID returns GoEntityID, an internal unique idntifier
func (*Go) GoRoutine ¶ added in v0.4.92
func (g *Go) GoRoutine() (threadID parl.ThreadID, goFunction *pruntime.CodeLocation)
func (*Go) SubGo ¶ added in v0.4.21
func (g *Go) SubGo(onFirstFatal ...parl.GoFatalCallback) (subGo parl.SubGo)
func (*Go) SubGroup ¶ added in v0.4.29
func (g *Go) SubGroup(onFirstFatal ...parl.GoFatalCallback) (subGroup parl.SubGroup)
func (*Go) ThreadInfo ¶ added in v0.4.29
func (g *Go) ThreadInfo() (threadData parl.ThreadData)
func (*Go) WaitCh ¶ added in v0.4.117
func (g *Go) WaitCh() (ch parl.AwaitableCh)
type GoError ¶ added in v0.4.29
type GoError struct {
// contains filtered or unexported fields
}
GoError is a wrapper around an error associating it with a Go goroutine and the situation in which this error occurred
func (*GoError) ErrContext ¶ added in v0.4.29
func (e *GoError) ErrContext() (errContext parl.GoErrorContext)
func (*GoError) ErrString ¶ added in v0.4.147
ErrString returns string representation of error
- if no error “OK”
- if not debug or panic, short error with location
- otherwise error with stack trace
func (*GoError) Error ¶ added in v0.4.29
Error returns a human-readable error message making GoError implement error
- for nil errors, empty string is returned
func (*GoError) IsThreadExit ¶ added in v0.4.29
type GoGroup ¶ added in v0.4.19
type GoGroup struct {
// contains filtered or unexported fields
}
GoGroup is a Go thread-group. Thread-safe.
- GoGroup has its own error channel and waitgroup and no parent thread-group.
- thread exits are processed by G1Done and the g1WaitGroup
- the thread-group terminates when its erropr channel closes
- non-fatal erors are processed by ConsumeError and the error channel
- new Go threads are handled by the g1WaitGroup
- SubGroup creates a subordinate thread-group using this threadgroup’s error channel
func (*GoGroup) Add ¶ added in v0.4.19
func (g *GoGroup) Add(goEntityID parl.GoEntityID, threadData *ThreadData)
Add processes a thread from this or a subordinate thread-group
func (*GoGroup) Cancel ¶ added in v0.4.28
func (g *GoGroup) Cancel()
Cancel signals shutdown to all threads of a thread-group.
func (*GoGroup) CascadeEnableTermination ¶ added in v0.4.69
CascadeEnableTermination manipulates wait groups of this goGroup and those of its parents to allow or prevent termination
func (*GoGroup) Ch ¶ added in v0.4.20
Ch returns a channel sending the all fatal termination errors when the FailChannel option is present, or only the first when both FailChannel and StoreSubsequentFail options are present.
func (*GoGroup) ConsumeError ¶ added in v0.4.29
ConsumeError receives non-fatal errors from a Go thread.
- Go.AddError delegates to this method
func (*GoGroup) Context ¶ added in v0.4.28
Context returns the context of this cancelAndContext.
- Context is used to detect cancel using the receive channel Context.Done.
- Context cancellation has happened when Context.Err is non-nil.
func (*GoGroup) EnableTermination ¶ added in v0.4.43
EnableTermination controls whether the thread-droup is allowed to terminate
- true is default
- period of false prevents terminating even if child-object count reaches zero
- invoking with true while child-object count is zero, terminates the thread-group regardless of previous enableTermination state. This is used prior to Wait when a thread-group was not used. Using the alternative Cancel would signal to threads to exit.
func (*GoGroup) FirstFatal ¶ added in v0.4.29
func (g *GoGroup) FirstFatal() (firstFatal *parl.OnceWaiterRO)
FirstFatal allows to await or inspect the first thread terminating with error. it is valid if this SubGo has LocalSubGo or LocalChannel options. To wait for first fatal error using multiple-semaphore mechanic:
firstFatal := g0.FirstFatal() for { select { case <-firstFatal.Ch(): …
To inspect first fatal:
if firstFatal.DidOccur() …
func (*GoGroup) FromGoGo ¶ added in v0.4.92
FromGoGo returns a parl.Go thread-features object invoked from another parl.Go object
- the Go return value is to be used as a function argument in a go-statement function-call launching a goroutine thread
func (*GoGroup) FromGoSubGo ¶ added in v0.4.92
func (g *GoGroup) FromGoSubGo(onFirstFatal ...parl.GoFatalCallback) (g1 parl.SubGo)
FromGoSubGo returns a subordinate thread-group witthout an error channel. Thread-safe.
func (*GoGroup) FromGoSubGroup ¶ added in v0.4.92
func (g *GoGroup) FromGoSubGroup(onFirstFatal ...parl.GoFatalCallback) (g2 parl.SubGroup)
FromGoSubGroup returns a subordinate thread-group with an error channel handling fatal errors only. Thread-safe.
func (*GoGroup) Go ¶ added in v0.4.29
Go returns a parl.Go thread-features object
- Go is invoked by a g0-package consumer
- the Go return value is to be used as a function argument in a go-statement function-call launching a goroutine thread
func (*GoGroup) GoDone ¶ added in v0.4.29
Done receives thread exits from threads in subordinate thread-groups
func (*GoGroup) Internals ¶ added in v0.4.131
func (g *GoGroup) Internals() ( isEnd func() bool, isAggregateThreads *atomic.Bool, setCancelListener func(f func()), endCh <-chan struct{}, )
Internals returns methods used by [g0debug.ThreadLogger]
func (*GoGroup) NamedThreads ¶ added in v0.4.43
func (g *GoGroup) NamedThreads() (threads []parl.ThreadData)
threads that have been named ordered by name
func (*GoGroup) SetDebug ¶ added in v0.4.43
func (g *GoGroup) SetDebug(debug parl.GoDebug, log ...parl.PrintfFunc)
SetDebug enables debug logging on this particular instance
- parl.NoDebug
- parl.DebugPrint
- parl.AggregateThread
func (*GoGroup) String ¶ added in v0.4.20
g1Group#3threads:1(1)g0.TestNewG1Group-g1-group_test.go:60
func (*GoGroup) SubGo ¶ added in v0.4.29
func (g *GoGroup) SubGo(onFirstFatal ...parl.GoFatalCallback) (g2 parl.SubGo)
newSubGo returns a subordinate thread-group witthout an error channel. Thread-safe.
- a SubGo has goGroupParent non-nil and isSubGo true
- the SubGo thread’s fatal and non-fatal errors are forwarded to its parent
- SubGo has FirstFatal mechanic but no error channel of its own.
- the SubGo’s Go invocations and thread-exits are processed by the SubGo’s wait-group and the thread-group of its parent
- cancel of the SubGo’s context signals termination to its own threads and all threads of its subordinate thread-groups
- the SubGo’s context is canceled when its parent’s context is canceled or any of its threads invoke the SubGo’s Cancel method
- the SubGo thread-group terminates when all threads in its own thread-group and that of any subordinate thread-groups have exited.
func (*GoGroup) SubGroup ¶ added in v0.4.29
func (g *GoGroup) SubGroup(onFirstFatal ...parl.GoFatalCallback) (g2 parl.SubGroup)
newSubGroup returns a subordinate thread-group with an error channel handling fatal errors only. Thread-safe.
- a SubGroup has goGroupParent non-nil and isSubGo false
- fatal errors from the SubGroup’s threads are sent on its own error channel
- non-fatal errors from the SubGroup’s threads are forwarded to the parent
- the SubGroup’s Go invocations and thread-exits are processed in the SubGroup’s wait-group and that of its parent
- cancel of the SubGroup’s context signals termination to its own threads and all threads of its subordinate thread-groups
- the SubGroup’s context is canceled when its parent’s context is canceled or any of its threads invoke the SubGroup’s Cancel method
- SubGroup thread-group terminates when its error channel closes after all of its threads and threads of its subordinate thread-groups have exited.
func (*GoGroup) Threads ¶ added in v0.4.43
func (g *GoGroup) Threads() (threads []parl.ThreadData)
the available data for all threads
func (*GoGroup) ThreadsInternal ¶ added in v0.4.93
func (g *GoGroup) ThreadsInternal() (m parli.ThreadSafeMap[parl.GoEntityID, *ThreadData])
ThreadsInternal returns values with the internal parl.GoEntityID key
func (*GoGroup) UpdateThread ¶ added in v0.4.29
func (g *GoGroup) UpdateThread(goEntityID parl.GoEntityID, threadData *ThreadData)
UpdateThread recursively updates thread information for a parl.Go object invoked when that Go fiorst obtains the information
func (*GoGroup) Wait ¶ added in v0.4.19
func (g *GoGroup) Wait()
Wait waits for all threads of this thread-group to terminate.
func (*GoGroup) WaitCh ¶ added in v0.4.112
func (g *GoGroup) WaitCh() (ch parl.AwaitableCh)
returns a channel that closes on subGo end similar to Wait
type ThreadData ¶ added in v0.4.29
type ThreadData struct {
// contains filtered or unexported fields
}
ThreadData contains identifiable information about a running thread.
- ThreadData does not have initialization
func (*ThreadData) Create ¶ added in v0.4.43
func (t *ThreadData) Create() (createLocation *pruntime.CodeLocation)
func (*ThreadData) Func ¶ added in v0.4.43
func (t *ThreadData) Func() (funcLocation *pruntime.CodeLocation)
func (*ThreadData) Get ¶ added in v0.4.29
func (t *ThreadData) Get() (threadID parl.ThreadID, createLocation pruntime.CodeLocation, funcLocation pruntime.CodeLocation, label string)
func (*ThreadData) LabeledString ¶ added in v0.4.92
func (t *ThreadData) LabeledString() (s string)
func (*ThreadData) Name ¶ added in v0.4.43
func (t *ThreadData) Name() (label string)
func (*ThreadData) SetCreator ¶ added in v0.4.29
func (t *ThreadData) SetCreator(cl *pruntime.CodeLocation)
SetCreator gets preliminary Go identifier: the line invoking Go()
func (*ThreadData) Short ¶ added in v0.4.43
func (t *ThreadData) Short() (s string)
"myThreadName:4"
func (*ThreadData) String ¶ added in v0.4.43
func (t *ThreadData) String() (s string)
"myThreadName:4_func:testing.tRunner()-testing.go:1446_cre:testing.(*T).Run()-testing.go:1493"
func (*ThreadData) ThreadID ¶ added in v0.4.29
func (t *ThreadData) ThreadID() (threadID parl.ThreadID)
threadID is the ID of the running thread
func (*ThreadData) Update ¶ added in v0.4.29
func (t *ThreadData) Update( threadID parl.ThreadID, createInvocation, goFunction *pruntime.CodeLocation, label string)
Update populates this object from a stack trace.
type ThreadSafeThreadData ¶ added in v0.4.37
type ThreadSafeThreadData struct {
// contains filtered or unexported fields
}
ThreadSafeThreadData controls access to a ThreadData object making it thread-safe.
- ThreadSafeThreadData does not have initialization
- haveThreadID indicates whether data is present
func NewThreadSafeThreadData ¶ added in v0.4.117
func NewThreadSafeThreadData() (t *ThreadSafeThreadData)
func (*ThreadSafeThreadData) Get ¶ added in v0.4.37
func (tw *ThreadSafeThreadData) Get() (thread *ThreadData)
Get returns a clone of the wrapped ThreadData object.
func (*ThreadSafeThreadData) HaveThreadID ¶ added in v0.4.37
func (tw *ThreadSafeThreadData) HaveThreadID() (haveThreadID bool)
HaveThreadID indicates whether Update has been invoked on this ThreadDataWrap object.
func (*ThreadSafeThreadData) SetCreator ¶ added in v0.4.37
func (tw *ThreadSafeThreadData) SetCreator(cl *pruntime.CodeLocation)
SetCreator gets preliminary Go identifier: the line invoking Go().
func (*ThreadSafeThreadData) ThreadID ¶ added in v0.4.37
func (tw *ThreadSafeThreadData) ThreadID() (threadID parl.ThreadID)
ThreadID returns the thread id of the running thread or zero if thread ID is missing.
func (*ThreadSafeThreadData) Update ¶ added in v0.4.37
func (tw *ThreadSafeThreadData) Update( threadID parl.ThreadID, createInvocation *pruntime.CodeLocation, goFunction *pruntime.CodeLocation, label string, )
Update populates the wrapped ThreadData from the stack trace.