Documentation
¶
Overview ¶
Package cascade is a system for tracking and controlling a series of goroutines. It allows for the creation of tracked routines, conversion of non-blocking functions into tracked goroutines, and manually tracking goroutines.
Cascade allows tying into various points of a lifecycle including "dying", "dead", and "done" states. Goroutines can be killed or cancelled at any point from any part of the program.
The system allows for a parent-child branching similar to cancelable contexts except that it ensures that routines tracked by a child Cascade fully exit before the routines tracked by the parent. This means that there is a guarantee that a parent routine will not exit before all of its children have cleanly exited and proper cleanup has been done.
You can also set actions to be run at each level at a guaranteed time and order. It is also possible to tie Cascades to Contexts or Contexts to Cascades to move between different systems.
Index ¶
- Constants
- type Cascade
- func (c *Cascade) Alive() bool
- func (c *Cascade) Cancel()
- func (c *Cascade) CancelAll()
- func (c *Cascade) CancelAllWithError(err error)
- func (c *Cascade) CancelWithError(err error) error
- func (c *Cascade) ChildCascade() *Cascade
- func (c *Cascade) Context(ctx context.Context) context.Context
- func (c *Cascade) Dead() <-chan interface{}
- func (c *Cascade) DoFirstOnKill(action func())
- func (c *Cascade) DoOnKill(action func())
- func (c *Cascade) Done() <-chan interface{}
- func (c *Cascade) Dying() <-chan interface{}
- func (c *Cascade) Error() error
- func (c *Cascade) Go(f func(*Cascade)) *Cascade
- func (c *Cascade) GoInLoop(f func()) *Cascade
- func (c *Cascade) GoInLoopWithBool(f func() bool) *Cascade
- func (c *Cascade) Hold()
- func (c *Cascade) IsDead() bool
- func (c *Cascade) Kill()
- func (c *Cascade) KillAll()
- func (c *Cascade) KillAllWithError(err error)
- func (c *Cascade) KillWithError(err error) error
- func (c *Cascade) Mark()
- func (c *Cascade) UnMark()
- func (c *Cascade) Wait()
- func (c *Cascade) WaitDone()
- func (c *Cascade) WithContext(ctx context.Context) (*Cascade, context.Context)
- func (c *Cascade) Wrap(f func(*Cascade))
- func (c *Cascade) WrapInLoop(f func())
- func (c *Cascade) WrapInLoopWithBool(f func() bool)
Constants ¶
const Version string = "1.0.0"
Version is the current version of Cascade.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Cascade ¶
type Cascade struct {
// contains filtered or unexported fields
}
Cascade is the core structure of the cascade package. It contains all of the non-public resources used to maintain all tracked routines.
func RootCascade ¶
func RootCascade() *Cascade
RootCascade creates a new Cascade that is fully-initialized and ready to go. This Cascade also acts as the root cascade which means that it is the highest-up parent.
Note about RootCascade and Errors ¶
When calling `KillAllWithError` or `CancelAllWithError`, the `RootCascade` Cascade is the only one that will receive the passed error.
func WithContext ¶
WithContext links a Context to a new `RootCascade`. When the provided Context is Cancelled, the Cascade will be killed.
The function also returns a child context that will be cancelled when the Cascade is killed or cancelled. (Regardless of the state of the parent Context)
func (*Cascade) Cancel ¶
func (c *Cascade) Cancel()
Cancel will kill the Cascade and any children (just like the `Kill` function) but will not run any set actions.
Note: This function blocks until all children and the specified Cascade have finished exiting.
func (*Cascade) CancelAll ¶
func (c *Cascade) CancelAll()
CancelAll will `Cancel` all Cascades in the whole tree from the `RootCascade` all the way to every child. No actions will be run.
Note: This function blocks until ALL Cascades have been cancelled and finished exiting.
func (*Cascade) CancelAllWithError ¶
CancelAllWithError will `Cancel` all Cascades in the whole tree from the `RootCascade` all the way to every child. No actions will be run. The provided `error` is set ONLY on the `RootCascade`
Notes:
This function blocks until ALL Cascades have been cancelled and finished exiting.
An error will be returned if an error has already been set on the current Cascade.
func (*Cascade) CancelWithError ¶
CancelWithError will kill the Cascade and any children (just like the `KillWithError` function) but will not run any set actions. The provided error will be set ONLY on the current Cascade.
Notes:
This function blocks until all children and the current Cascade have finished exiting.
An error will be returned if an error has already been set on the current Cascade.
func (*Cascade) ChildCascade ¶
ChildCascade creates a new Cascade which is a child of the current Cascade.
The child Cascade being killed or cancelled will not kill or cancel the parent.
func (*Cascade) Context ¶
Context returns a `context.Context` that will be cancelled when the Cascade that it was generated from is killed or cancelled.
If a Context is provided, it will be used as the parent for the new Context. If `nil` is passed, either the Cascade's parent Context (if it exists) or `context.Background()` will be used as the parent.
func (*Cascade) Dead ¶
func (c *Cascade) Dead() <-chan interface{}
Dead provides a channel that will close once the Cascade is considered dead.
This can be used as a signal to indicate when all goroutines have exited. However, actions may not have run yet
func (*Cascade) DoFirstOnKill ¶
func (c *Cascade) DoFirstOnKill(action func())
DoFirstOnKill adds a function to the list of actions that should be performed when the Cascade is killed.
Functions are added in a LIFO order and will be executed in order.
Note: These actions will NOT be run if the Cascade is cancelled instead of killed.
func (*Cascade) DoOnKill ¶
func (c *Cascade) DoOnKill(action func())
DoOnKill adds a function to the list of actions that should be performed when the Cascade is killed.
Functions are added in a FIFO order and will be executed in order.
Note: These actions will NOT be run if the Cascade is cancelled instead of killed.
func (*Cascade) Done ¶
func (c *Cascade) Done() <-chan interface{}
Done provides a channel that will close once the Cascade is completely done.
This can be used as a signal to indicate when all goroutines have exited and all actions have been completed.
func (*Cascade) Dying ¶
func (c *Cascade) Dying() <-chan interface{}
Dying provides a channel that will close once the Cascade is considered dying.
This should be what goroutines use to determine when to exit.
func (*Cascade) Go ¶
Go wraps a function that takes a Cascade as an argument and runs it as a tracked goroutine.
The returned Cascade is a child of the current Cascade that is tracking the provided function.
The provided function MUST implement an exit condition using the provided Cascade.
Example Function:
func(c *Cascade) { // Do Something <-c.Dying() // Block until the exit condition }
func (*Cascade) GoInLoop ¶
GoInLoop wraps a function inside a loop and runs it as a tracked goroutine.
The provided function MUST not block, it will continue getting called until the Cascade is killed or cancelled.
The returned Cascade is a child of the current Cascade that is tracking the provided function.
Warning: The only way to exit the function is to kill or cancel the Cascade.
func (*Cascade) GoInLoopWithBool ¶
GoInLoopWithBool wraps a function inside a loop and runs it as a tracked goroutine as long as the function returns `true`
The provided function MUST not block, it will continue getting called until the Cascade is killed or cancelled or the provided function returns `false`
The returned Cascade is a child of the current Cascade that is tracking the provided function.
func (*Cascade) Hold ¶
func (c *Cascade) Hold()
Hold blocks until the Cascade is considered dying.
This should be what goroutines use to determine when to exit.
func (*Cascade) Kill ¶
func (c *Cascade) Kill()
Kill will kill the Cascade and any children (just like the `Cancel` function) and will run any set actions.
Note: This function blocks until all children and the specified Cascade have finished exiting.
func (*Cascade) KillAll ¶
func (c *Cascade) KillAll()
KillAll will `Kill` all Cascades in the whole tree from the `RootCascade` all the way to every child. All actions will be run.
Note: This function blocks until ALL Cascades have been killed and finished exiting.
func (*Cascade) KillAllWithError ¶
KillAllWithError will `Kill` all Cascades in the whole tree from the `RootCascade` all the way to every child. All actions will be run. The provided `error` is set ONLY on the `RootCascade`
Notes:
This function blocks until ALL Cascades have been killed and finished exiting.
An error will be returned if an error has already been set on the current Cascade.
func (*Cascade) KillWithError ¶
KillWithError will kill the Cascade and any children (just like the `CancelWithError` function) and will run any set actions. The provided error will be set ONLY on the current Cascade.
Notes:
This function blocks until all children and the current Cascade have finished exiting.
An error will be returned if an error has already been set on the current Cascade.
func (*Cascade) Mark ¶
func (c *Cascade) Mark()
Mark marks a goroutine as being tracked by a Cascade. It should be used similar to `Add` in `sync.WaitGroup` and called at the beginning of a goroutine.
A marked goroutine MUST have an exit condition set for when the Cascade is in a dying state. Either `<-Dying()` or `Hold()` should be used.
A marked goroutine MUST also `UnMark` once it has exited. This is most easily accomplished by using a `defer`.
Example of a marked goroutine:
c := RootCascade() go func() { c.Mark() // Mark the goroutine as tracked defer c.UnMark() // UnMark the goroutine once it's done. // Do something Hold() // Wait for Cascade kill or cancel. }() // Additional Code Not Shown
func (*Cascade) UnMark ¶
func (c *Cascade) UnMark()
UnMark removes the mark from a goroutine being tracked by a Cascade. It should be used similar to `Done` in `sync.WaitGroup` and called whenever a goroutine that has called `Mark` exits.
See the docs for `Mark` for a usage example.
func (*Cascade) Wait ¶
func (c *Cascade) Wait()
Wait until the Cascade is considered dead.
This can be used as a signal to indicate when all goroutines have exited. However, actions may not have run yet
func (*Cascade) WaitDone ¶
func (c *Cascade) WaitDone()
WaitDone blocks until the Cascade is completely done.
This can be used as a signal to indicate when all goroutines have exited and all actions have been completed.
func (*Cascade) WithContext ¶
WithContext links a Context to a new child Cascade. When the provided Context is Cancelled, the child Cascade will be killed.
The function also returns a child context that will be cancelled when the Cascade is killed or cancelled. (Regardless of the state of the parent Context)
func (*Cascade) Wrap ¶
Wrap wraps a function that takes a Cascade as an argument and turns it into a tracked function.
This is NOT a goroutine and will block until the provided function exits.
The provided function MUST implement an exit condition using the provided Cascade.
For an example of a suitable function, see the example for the `Go` function.
func (*Cascade) WrapInLoop ¶
func (c *Cascade) WrapInLoop(f func())
WrapInLoop wraps a function inside a loop and runs it as a tracked function.
This is NOT a goroutine and will block until the provided function exits.
The provided function MUST not block, it will continue getting called until the Cascade is killed or cancelled.
Warning: The only way to exit the function is to kill or cancel the Cascade.
func (*Cascade) WrapInLoopWithBool ¶
WrapInLoopWithBool wraps a function inside a loop and runs it as a tracked function as long as the provided function returns `true`
This is NOT a goroutine and will block until the provided function exits.
The provided function MUST not block, it will continue getting called until the Cascade is killed or cancelled or the provided function returns `false`