Documentation ¶
Overview ¶
Package cap offers an API to model applications as an static supervision tree of goroutines, with monitoring rules that follow semantics from Erlang's OTP Library.
This implementation allows the creation of a root supervisor, sub-trees and workers; it also offers various error monitoring/restart strategies and start and shutdown ordering guarantees.
Why Supervision Trees ¶
Goroutines are a great tool to solve many jobs, but, alone, they come with a few drawbacks:
* We don't have easy ways to know when a goroutine stopped working (e.g. random panic) other than the main program crashing.
* As soon as we spawn a group of goroutines, we don't have any guarantees they will start in the order we anticipated.
* The way goroutines are designed make it very easy to not follow golang best practices like message passing; instead, it is easy to reach mutexes.
Granted, we can use tools like gochans, sync.WaitGroup, sync.Cond, etc. to deal with these issues, but, they are very low-level and there is unnecessary boilerplate involved in order to make them work.
Capataz offers a declarative API that allows developers to easily manage goroutine error handling and start/stop system mechanisms through type composition.
A great benefit, is that you can compose several sub-systems together into a bigger supervised system, increasing the reliability of your application altogether.
Capataz offers a few types and functions that you need to learn upfront to be effective with it.
Worker ¶
A worker is equivalent to a Goroutine. You create a worker using the NewWorker function
myWorker := cap.NewWorker( // (1) "my-worker", // (2) func(ctx context.Context) error { select { case <-ctx.Done(): // my bussiness logic here }, // (3) cap.WithRestart(cap.Permanent), // (4) cap.WithShutdown(cap.Timeout(1 * time.Second)), })
The first argument (1) is a name. This name is used for metadata/tracing purposes and it will be very handy when monitoring your application behavior.
The second argument (2) is the function you want to run on a goroutine.
This function receives a context.Context record; you must use this context to check for stop signals that may get triggered when failures are detected, and add cleanup code if you allocated some resource.
The function also returns an error, which may indicate that the worker goroutine finished on a bad state. Depending on your setup, an error may indicate a supervisor that the worker goroutine needs to get restarted.
The third argument (3) is a WorkerOpt. This option in particular indicates that the worker goroutine should always get restarted, whether the function returns an error or returns nil. You can check the WithRestart function for more available options.
The fourth argument (4) is also a WorkerOpt. This option specifies that the supervisor must wait at least 1 second to stop "my-worker" before giving up.
All starts and stops of Worker goroutines are managed by its Supervisor, so you need to plug this worker into a SupervisorSpec in order to see it in action.
SupervisorSpec ¶
A supervisor spec is a specification of a supervision (sub-)tree. It is responsible for creating the Supervisor that will start, restart, and stop all the specified workers or sub-trees.
You can create a SupervisorSpec using the NewSupervisorSpec function
root := cap.NewSupervisorSpec( // (1) "my-supervisor", // (2) cap.WithNodes(myWorker, myOtherWorker, cap.Subtree(mySubsystem)), // (3) cap.WithStartOrder(cap.LeftToRight), // (4) cap.WithStrategy(cap.OneForOne), )
The first argument (1) is a name. Like in NewWorker call, this name is going to be used for monitoring/tracing purposes.
The second argument (2) is a function that returns a pre-defined BuildNodesFn, the function describes all the nodes this supervisor must monitor. We have two workers (myWorker, myOtherWorker) and one subtree (mySubsystem), which is another supervisor that monitors other workers.
The third argument (3) is an Opt. This option specifies how these tree nodes should get started. the LeftToRight value indicates that when starting, it should start with myWorker, then myOtherWorker and end with mySubsystem.
This API will guarantee that the mySubsystem sub-tree won't start until myOtherWorker starts, and that one won't start until myWorker starts. When root shuts down, it will stop each child node in reverse order, starting with mySubsystem, then myOtherWorker and finally myWorker.
The fourth argument (4) is an Opt. This option specifies how children should get restarted when one of them fails. In this particular example, only the failing child node will get restarted. Check the WithStrategy docs for more details.
Once we have a SupervisorSpec, we have the blueprint to start a system, spawning each goroutine we need in order. Note that all the wiring of resources is happening at build time. The actual allocation of resources comes at later step.
We will use this SupervisorSpec to create a Supervisor value.
Supervisor ¶
To create Supervisor, you need to call the Start method of a SupervisorSpec value
sup, startErr := root.Start()
This call will return a Supervisor record or an error. The error may happen when one of the supervision tree children nodes is not able to allocate some IO resource and reports it failed to Start (see NewWithStart and NewSupervisorSpec for details).
The Start call is synchronous, the program will not continue until all worker nodes and sub-trees are started in the specified order. With the SupervisorSpec example above the following supervision tree will be spawned
root | ` root/my-worker (spawned goroutine) | ` root/my-other-worker (spawned goroutine) | ` my-subsystem | ` <other workers or sub-trees here>
At this point, all your program workers should have allocated their resources and running as expected. If you want to stop the system, you can call the Stop method on the returned supervisor:
stopErr := sup.Stop()
The stopErr error will tell you if any of the children failed to stop. You may also join the main goroutine with the root supervisor monitor goroutine using the Wait method
supErr := sup.Wait()
Resources in Workers ¶
There are times when an IO resource belongs to a single worker, and it doesn't make sense to consider a worker "started" until this resource is allocated.
For this use case you can create a Worker goroutine that receives a callback function that indicates that the Worker was started (or failed to start).
Lets use the NewWorkerWithNotifyStartFn function to model this behavior:
func newReportGenWorker( name string, dbConfig dbConfig, reportCh chan Report, opts ...cap.WorkerOpt, ) cap.Worker { return cap.NewWorkerWithNotifyStartFn( name, func(ctx context.Cotnext, notifyStart cap.NotifyStartFn) error { db, err := openDB(dbConfig) if err != nil { // (1) notifyStart(err) return err } // (2) notifyStart(nil) return runDBWorker(ctx, db, reportCh) }, opts..., ) } // Look ma, no capataz dependencies func runDBWorker(ctx context.Context, db db.DB, reportCh chan Report) error { // Business Logic Here }
We have a Worker that is reponsible to send certain reports to a given channel that some consumer is going to use. The Worker goroutine is the only one accessing the database, so it is responsible for initializing it. It uses the notifyStart function to indicate if there was an error on start when connecting to the database. If this happened (1), the start procedure of the root supervisor will stop and abort, if not, the Start routine won't continue until the worker notifies is ready (2).
What about that channel though?
Where do we create this channel that this producer and possibly a consumer use to communicate?
For this, we need to manage resources in sub-trees.
Resources in Sub-trees ¶
For the example above, we could create the channel at the top-level of our application (main function) and pass them as arguments there; however, there is a drawback with doing it that way. If for some reason the channel gets closed, you get a worker that is always going to fail, until the error tolerance of all the supervisors is met (hopefully) and it crashes hard.
Another approach is to have a subtree create the channel at the same level as the worker and producer (which the subtree supervisor will be monitoring). That way, if for some reason, the subtree supervisor fails, it will create a new gochan and restart the producer and the consumer.
To do this, we need to define a custom BuildNodesFn in our NewSupervisorSpec call.
func reportSubSystem( dbConfig dbConfig, dialConfig dialConfig, ) cap.SupervisorSpec { return cap.NewSupervisorSpec( "reports-subsystem", // (1) func() ([]cap.Node, cap.CleanupResourcesFn, error) { // (2) reportCh := make(chan Report) // (3) cleanupFn : func() error { close(reportCh) return nil } // (4) return []cap.Node{ newReportGenWorker(dbConfig, reportCh), newReportEmitter(dialConfig, reportCh), }, cleanupFn, nil }, cap.WithStrategy(cap.OneForOne), cap.WithStartOrder(cap.LeftToRight), ) }
On the code above, instead of using the cap.WithNodes function, we define our own BuildNodesFn (1). This function creates a gochan for Report values that both producer and consumer are going to use (2).
We then declare a cleanup function that closes the allocated gochan in case this supervisor gets restarted or stopped (3), and finally, it returns the nodes that the supervisor is going to monitor (4), the cleanup function and a nil error.
If there is a restart of this supervisor, the cleanup function gets called, and the logic inside the BuildNodesFn gets called again, restarting this specific sub-system and without affecting other parts of the bigger system.
Other Examples ¶
Check the examples directory in the Github repository for more examples ¶
https://github.com/capatazlib/go-capataz/tree/master/examples
Index ¶
- Variables
- type BuildNodesFn
- type CleanupResourcesFn
- type DynSupervisor
- type ErrKVs
- type Event
- type EventCriteria
- type EventNotifier
- type EventTag
- type HealthReport
- type HealthcheckMonitor
- type Node
- type NodeTag
- type NotifyStartFn
- type Opt
- type Order
- type ReliableNotifierOpt
- type Restart
- type RestartToleranceReached
- type Shutdown
- type Spawner
- type Strategy
- type Supervisor
- type SupervisorBuildError
- type SupervisorRestartError
- type SupervisorSpec
- type SupervisorStartError
- type SupervisorTerminationError
- type WorkerOpt
Constants ¶
This section is empty.
Variables ¶
var ApplyEventCriteria = n.ApplyEventCriteria
ApplyEventCriteria forwards Event records that match positively the given criteria to the given EventNotifier
Since: 0.1.0
var EAnd = n.EAnd
EAnd joins a slice of EventCriteria with an "and" statement. A call without arguments will accept all given events.
Since: 0.1.0
var EHasNameSuffix = n.EHasNameSuffix
EHasNameSuffix returnes true if the runtime name of the node that emitted the event matches the given suffix
Since: 0.1.0
var EHasRuntimeName = n.EHasRuntimeName
EHasRuntimeName returns true if the runtime name of the node that emitted the event matches the given name
Since: 0.1.0
var EInSubtree = n.EInSubtree
EInSubtree allows to filter s.Event that were sent from an specific subtree
Since: 0.1.0
var EIsFailure = n.EIsFailure
EIsFailure returns true if the event represent a node failure
Since: 0.1.0
var EIsSupervisorRestartError = n.EIsSupervisorRestartError
EIsSupervisorRestartError returns true if the event represents a restart tolerance reached error
Since: 0.1.0
var EIsWorkerFailure = n.EIsWorkerFailure
EIsWorkerFailure returns true if the event represents a worker failure
Since: 0.1.0
var ENot = n.ENot
ENot negates the result from a given EventCriteria
Since: 0.1.0
var EOr = n.EOr
EOr joins a slice of EventCriteria with an "or" statement. A call without arguments wil reject all given events.
Since: 0.1.0
var ExplainError = s.ExplainError
ExplainError is a utility function that explains capataz errors in a human-friendly way. Defaults to a call to error.Error() if the underlying error does not come from the capataz library.
Since: 0.1.0
var GetWorkerName = c.GetNodeName
GetWorkerName returns the runtime name of a supervised goroutine by plucking it up from the given context.
Since: 0.0.0
var HealthyReport = s.HealthyReport
HealthyReport represents a healthy report
Since: 0.0.0
var Indefinitely = c.Indefinitely
Indefinitely is a Shutdown value that specifies the parent supervisor must wait indefinitely for the worker goroutine to stop executing. You can specify this option using the WithShutdown function
Since: 0.0.0
var LeftToRight = s.LeftToRight
LeftToRight is an Order that specifies children start from left to right
Since: 0.0.0
var NewDynSubtree = s.NewDynSubtree
NewDynSubtree builds a worker that has receives a Spawner that allows it to create more child workers dynamically in a sub-tree.
Note: The Spawner is automatically managed by the supervision tree, so clients are not required to terminate it explicitly.
since: 0.2.0
var NewDynSubtreeWithNotifyStart = s.NewDynSubtreeWithNotifyStart
NewDynSubtreeWithNotifyStart accomplishes the same goal as NewDynSubtree with the addition of passing an extra argument (notifyStart callback) to the startFn function parameter.
since: 0.2.0
var NewDynSupervisor = s.NewDynSupervisor
NewDynSupervisor creates a DynamicSupervisor which can start workers at runtime in a procedural manner. It receives a context and the supervisor name (for tracing purposes).
When to use a DynSupervisor?
If you want to run supervised worker routines on dynamic inputs. This is something that a regular Supervisor cannot do, as it needs to know the children nodes at construction time.
Differences to Supervisor ¶
As opposed to a Supervisor, a DynSupervisor:
* Cannot receive node specifications to start them in an static fashion
* It is able to spawn workers dynamically
- In case of a hard crash and following restart, it will start with an empty list of children
Since: 0.0.0
var NewHealthcheckMonitor = s.NewHealthcheckMonitor
NewHealthcheckMonitor offers a way to monitor a supervision tree health from events emitted by it.
maxAllowedFailures: the threshold beyond which the environment is considered
unhealthy.
maxAllowedRestartDuration: the restart threshold, which if exceeded, indicates
an unhealthy environment. Any process that fails to restart under the threshold results in an unhealthy report
Since: 0.0.0
var NewReliableNotifier = n.NewReliableNotifier
NewReliableNotifier is an EventNotifier that guarantees it will never panic the execution of its caller, and that it will continue sending events to notifiers despite previous panics
Since: 0.1.0
var NewSupervisorSpec = s.NewSupervisorSpec
NewSupervisorSpec creates a SupervisorSpec. It requires the name of the supervisor (for tracing purposes) and some children nodes to supervise.
Monitoring children that do not share resources ¶
This is intended for situations where you need worker goroutines that are self-contained running in the background.
To specify a group of children nodes, you need to use the WithNodes utility function. This function may receive Subtree or Worker nodes.
Example:
cap.NewSupervisorSpec("root", // (1) // Specify child nodes to spawn when this supervisor starts cap.WithNodes( cap.Subtree(subtreeSupervisorSpec), workerChildSpec, ), // (2) // Specify child nodes start from right to left (reversed order) and // stop from left to right. cap.WithStartOrder(cap.RightToLeft), )
Monitoring nodes that share resources ¶
Sometimes, you want a group of children nodes to interact between each other via some shared resource that only the workers know about (for example, a gochan, a db datapool, etc).
You are able to specify a custom function (BuildNodesFn) that allocates and releases these resources.
This function should return:
* The children nodes of the supervision tree
* A function that cleans up the allocated resources (CleanupResourcesFn)
* An error, but only in the scenario where a resource initialization failed
Example:
cap.NewSupervisorSpec("root", // (1) // Implement a function that return all nodes to be supervised. // When this supervisor gets (re)started, this function will be called. // Imagine this function as a factory for it's children. func() ([]cap.Node, cap.CleanupResourcesFn, error) { // In this example, child nodes have a shared resource (a gochan) // and it gets passed to their constructors. buffer := make(chan MyType) nodes := []cap.Node{ producerWorker(buffer), consumerWorker(buffer), } // We create a function that gets executed when the supervisor // shuts down. cleanup := func() { close(buffer) } // We return the allocated Node records and the cleanup function return nodes, cleanup, nil }, // (2) cap.WithStartOrder(cap.RightToLeft), )
Dealing with errors ¶
Given resources can involve IO allocations, using this functionality opens the door to a few error scenarios:
1) Resource allocation returns an error
In this scenario, the supervision start procedure will fail and it will follow the regular shutdown procedure: the already started nodes will be terminated and an error will be returned immediately.
2) Resource cleanup returns an error
In this scenario, the termination procedure will collect the error and report it in the returned SupervisorError.
3) Resource allocation/cleanup hangs
This library does not handle this scenario. Is the responsibility of the user of the API to implement start timeouts and cleanup timeouts inside the given BuildNodesFn and CleanupResourcesFn functions.
Since: 0.0.0
var NewWorker = s.NewWorker
NewWorker creates a Node that represents a worker goroutine. It requires two arguments: a name that is used for runtime tracing and a startFn function.
The name argument ¶
A name argument must not be empty nor contain forward slash characters (e.g. /), otherwise, the system will panic[*].
[*] This method is preferred as opposed to return an error given it is considered a bad implementation (ideally a compilation error).
The startFn argument ¶
The startFn function is where your business logic should be located. This function will be running on a new supervised goroutine.
The startFn function will receive a context.Context record that *must* be used inside your business logic to accept stop signals from its parent supervisor.
Depending on the Shutdown values used with the WithShutdown settings of the worker, if the `startFn` function does not respect the given context, the parent supervisor will either block forever or leak goroutines after a timeout has been reached.
var NewWorkerWithNotifyStart = s.NewWorkerWithNotifyStart
NewWorkerWithNotifyStart accomplishes the same goal as NewWorker with the addition of passing an extra argument (notifyStart callback) to the startFn function parameter.
The NotifyStartFn argument ¶
Sometimes you want to consider a goroutine started after certain initialization was done; like doing a read from a Database or API, or some socket is bound, etc. The NotifyStartFn is a callback that allows the spawned worker goroutine to signal when it has officially started.
It is essential to call this callback function in your business logic as soon as you consider the worker is initialized, otherwise the parent supervisor will block and eventually fail with a timeout.
Report a start error on NotifyStartFn ¶
If for some reason, a child node is not able to start correctly (e.g. DB connection fails, network is kaput), the node may call the given NotifyStartFn function with the impending error as a parameter. This will cause the whole supervision system start procedure to abort.
Since: 0.0.0
var OneForAll = s.OneForAll
OneForAll is an Strategy that tells the Supervisor to restart all the siblings of a failed child process
Since: 0.2.0
var OneForOne = s.OneForOne
OneForOne is an Strategy that tells the Supervisor to only restart the child process that errored
Since: 0.0.0
var Permanent = c.Permanent
Permanent specifies that a goroutine should be restarted whether or not there are errors.
You can specify this option using the WithRestart function ¶
Since: 0.0.0
var ProcessCompleted = s.ProcessCompleted
ProcessCompleted is an Event that indicates a process finished without errors
Since: 0.0.0
var ProcessFailed = s.ProcessFailed
ProcessFailed is an Event that indicates a process reported an error
Since: 0.0.0
var ProcessStartFailed = s.ProcessStartFailed
ProcessStartFailed is an Event that indicates a process failed to start
Since: 0.0.0
var ProcessStarted = s.ProcessStarted
ProcessStarted is an Event that indicates a process started
Since: 0.0.0
var ProcessTerminated = s.ProcessTerminated
ProcessTerminated is an Event that indicates a process was stopped by a parent supervisor
Since: 0.0.0
var RightToLeft = s.RightToLeft
RightToLeft is an Order that specifies children start from right to left
Since: 0.0.0
var Subtree = s.Subtree
Subtree transforms SupervisorSpec into a Node. This function allows you to insert a black-box sub-system into a bigger supervised system.
Note the subtree SupervisorSpec is going to inherit the event notifier from its parent supervisor.
Example:
// Initialized a SupervisorSpec that doesn't know anything about other // parts of the systems (e.g. is self-contained) networkingSubsystem := cap.NewSupervisorSpec("net", ...) // Another self-contained system filesystemSubsystem := cap.NewSupervisorSpec("fs", ...) // SupervisorSpec that is started in your main.go cap.NewSupervisorSpec("root", cap.WithNodes( cap.Subtree(networkingSubsystem), cap.Subtree(filesystemSubsystem), ), )
Since: 0.0.0
var SupervisorT = c.Supervisor
SupervisorT is a NodeTag used to indicate a goroutine is running another supervision tree
Since: 0.0.0
var Temporary = c.Temporary
Temporary specifies that the goroutine should not be restarted under any circumstances
You can specify this option using the WithRestart function ¶
Since: 0.0.0
var Timeout = c.Timeout
Timeout is a Shutdown function that returns a value that indicates the time that the supervisor will wait before "force-killing" a worker goroutine. This function receives a time.Duration value. You can specify this option using the WithShutdown function.
* Warning
Is important to emphasize that golang **does not** provide a "force-kill" mechanism for goroutines.
There is no known way to kill a goroutine via a signal other than using context.Done, which the supervised goroutine must observe and respect.
If the timeout is reached and the goroutine does not stop (because the worker goroutine is not using the offered context value), the supervisor will continue with the shutdown procedure (reporting a shutdown error), possibly leaving the goroutine running in memory (e.g. memory leak)
Since: 0.0.0
var Transient = c.Transient
Transient specifies that a goroutine should be restarted if and only if the goroutine failed with an error. If the goroutine finishes without errors it is not restarted again.
You can specify this option using the WithRestart function ¶
Since: 0.0.0
var WithCapturePanic = c.WithCapturePanic
WithCapturePanic is a WorkerOpt that specifies if panics raised by this worker should be treated as errors.
Since: 0.0.0
var WithEntrypointBufferSize = n.WithEntrypointBufferSize
WithEntrypointBufferSize sets the buffer size for entrypoint of the reliable notifier.
since: 0.3.0
var WithNodes = s.WithNodes
WithNodes allows the registration of child nodes in a SupervisorSpec. Node records passed to this function are going to be supervised by the Supervisor created from a SupervisorSpec.
Check the documentation of NewSupervisorSpec for more details and examples.
var WithNotifier = s.WithNotifier
WithNotifier is an Opt that specifies a callback that gets called whenever the supervision system reports an Event
This function may be used to observe the behavior of all the supervisors in the systems, and it is a great place to hook in monitoring services like logging, error tracing and metrics gatherers
Since: 0.0.0
var WithNotifierBufferSize = n.WithNotifierBufferSize
WithNotifierBufferSize sets the buffer size for each notifier.
since: 0.3.0
var WithNotifierTimeout = n.WithNotifierTimeout
WithNotifierTimeout sets the maximum allowed time the reliable notifier is going to wait for a notifier function to be ready to receive an event (defaults to 10 millis).
since: 0.1.0
var WithOnNotifierTimeout = n.WithOnNotifierTimeout
WithOnNotifierTimeout sets callback that gets executed when a given notifier is so slow to get an event that it gets skipped. You need to ensure the given callback does not block.
Since: 0.1.0
var WithOnReliableNotifierFailure = n.WithOnReliableNotifierFailure
WithOnReliableNotifierFailure sets a callback that gets executed when a failure occurs on the event broadcasting logic. You need to ensure the given callback does not block.
Since: 0.1.0
var WithOrder = WithStartOrder
WithOrder is a backwards compatible alias to WithStartOrder
Deprecated: Use WithStartOrder instead
var WithRestart = c.WithRestart
WithRestart is a WorkerOpt that specifies how the parent supervisor should restart this worker after an error is encountered.
Possible values may be:
* Permanent -- Always restart worker goroutine
* Transient -- Only restart worker goroutine if it fails
* Temporary -- Never restart a worker goroutine (go keyword behavior)
Since: 0.0.0
var WithRestartTolerance = s.WithRestartTolerance
WithRestartTolerance is a Opt that specifies how many errors the supervisor should be willing to tolerate before giving up restarting and fail.
If the tolerance is met, the supervisor is going to fail, if this is a sub-tree, this error is going to be handled by a grand-parent supervisor, restarting the tolerance again.
Example
// Tolerate 10 errors every 5 seconds // // - if there is 11 errors in a 5 second window, it makes the supervisor fail // WithRestartTolerance(10, 5 * time.Second)
Since: 0.1.0
var WithShutdown = c.WithShutdown
WithShutdown is a WorkerOpt that specifies how the shutdown of the worker is going to be handled. Read Indefinitely and Timeout shutdown values documentation for details.
Possible values may be:
* Indefinitely -- Wait forever for the shutdown of this worker goroutine
* Timeout(time.Duration) -- Wait for a duration of time before giving up shuting down this worker goroutine
Since: 0.0.0
var WithStartOrder = s.WithStartOrder
WithStartOrder is an Opt that specifies the start/stop order of a supervisor's children nodes
Possible values may be:
* LeftToRight -- Start children nodes from left to right, stop them from right to left
* RightToLeft -- Start children nodes from right to left, stop them from left to right
Since: 0.0.0
var WithStrategy = s.WithStrategy
WithStrategy is an Opt that specifies how children nodes of a supervisor get restarted when one of the nodes fails
Possible values may be:
* OneForOne -- Only restart the failing child
* OneForAll (Not Implemented Yet) -- Restart the failing child and all its siblings[*]
[*] This option may come handy when all the other siblings depend on one another to work correctly.
Since: 0.0.0
var WithTag = c.WithTag
WithTag is a WorkerOpt that sets the given NodeTag on Worker.
Do not use this function if you are not extending capataz' API.
Since: 0.0.0
var WithTolerance = c.WithTolerance
WithTolerance is a WorkerOpt that specifies how many errors the supervisor should be willing to tolerate before giving up restarting and fail.
Deprecated: Use WithRestartTolerance instead.
Since: 0.0.0
var WorkerT = c.Worker
WorkerT is a NodeTag used to indicate a goroutine is a worker that run some business-logic
Since: 0.0.0
Functions ¶
This section is empty.
Types ¶
type BuildNodesFn ¶
type BuildNodesFn = s.BuildNodesFn
BuildNodesFn is a function that returns a list of nodes
Check the documentation of NewSupervisorSpec for more details and examples.
Since: 0.0.0
type CleanupResourcesFn ¶
type CleanupResourcesFn = s.CleanupResourcesFn
CleanupResourcesFn is a function that cleans up resources that were allocated in a BuildNodesFn function.
Check the documentation of NewSupervisorSpec for more details and examples ¶
Since: 0.0.0
type DynSupervisor ¶
type DynSupervisor = s.DynSupervisor
DynSupervisor is a supervisor that can spawn workers in a procedural way.
Since: 0.0.0
type ErrKVs ¶
ErrKVs is an utility interface used to get key-values out of Capataz errors
Since: 0.0.0
type Event ¶
Event is a record emitted by the supervision system. The events are used for multiple purposes, from testing to monitoring the healthiness of the supervision system.
Since: 0.0.0
type EventCriteria ¶
type EventCriteria = n.EventCriteria
EventCriteria is an utility that allows us to specify a matching criteria to a specific supervision event
Since: 0.1.0
type EventNotifier ¶
type EventNotifier = s.EventNotifier
EventNotifier is a function that is used for reporting events from the from the supervision system.
Check the documentation of WithNotifier for more details.
Since: 0.0.0
type EventTag ¶
EventTag specifies the type of Event that gets notified from the supervision system
Since: 0.0.0
type HealthReport ¶
type HealthReport = s.HealthReport
HealthReport contains a report for the HealthMonitor
Since: 0.0.0
type HealthcheckMonitor ¶
type HealthcheckMonitor = s.HealthcheckMonitor
HealthcheckMonitor listens to the events of a supervision tree events, and assess if the supervisor is healthy or not
Since: 0.0.0
type Node ¶
Node represents a tree node in a supervision tree, it could either be a Subtree or a Worker
Since: 0.0.0
type NodeTag ¶
NodeTag specifies the type of node that is running. This is a closed set given we will only support workers and supervisors
Since: 0.0.0
type NotifyStartFn ¶
type NotifyStartFn = c.NotifyStartFn
NotifyStartFn is a function given to worker nodes that allows them to notify the parent supervisor that they are officialy started.
The argument contains an error if there was a failure, nil otherwise.
See the documentation of NewWorkerWithNotifyStart for more details ¶
Since: 0.0.0
type Order ¶
Order specifies the order in which a supervisor is going to start its node children. The stop order is the reverse of the start order.
Since: 0.0.0
type ReliableNotifierOpt ¶
type ReliableNotifierOpt = n.ReliableNotifierOpt
ReliableNotifierOpt allows clients to tweak the behavior of an EventNotifier instance built with NewReliableNotifier
Since: 0.1.0
type RestartToleranceReached ¶
type RestartToleranceReached = s.RestartToleranceReached
RestartToleranceReached is an error that gets reported when a supervisor has restarted a child so many times over a period of time that it does not make sense to keep restarting.
Since: 0.0.0
type Shutdown ¶
Shutdown is an enum type that indicates how the parent supervisor will handle the stoppping of the worker goroutine
Since: 0.0.0
type Strategy ¶
Strategy specifies how children get restarted when one of them reports an error
Since: 0.0.0
type Supervisor ¶
type Supervisor = s.Supervisor
Supervisor represents the root of a tree of goroutines. A Supervisor may have leaf or sub-tree children, where each of the nodes in the tree represent a goroutine that gets automatic restart abilities as soon as the parent supervisor detects an error has occured. A Supervisor will always be generated from a SupervisorSpec
Since: 0.0.0
type SupervisorBuildError ¶
type SupervisorBuildError = s.SupervisorBuildError
SupervisorBuildError wraps errors returned from a client provided function that builds the supervisor nodes, enhancing it with supervisor information
Since: 0.0.0
type SupervisorRestartError ¶
type SupervisorRestartError = s.SupervisorRestartError
SupervisorRestartError wraps an error tolerance surpassed error from a child node, enhancing it with supervisor information and possible termination errors on other siblings
Since: 0.0.0
type SupervisorSpec ¶
type SupervisorSpec = s.SupervisorSpec
SupervisorSpec represents the specification of a static supervisor; it serves as a template for the construction of a runtime supervision tree. In the SupervisorSpec you can specify settings like:
* The children (workers or sub-trees) you want spawned in your system when it starts
* The order in which the supervised node children get started
* Notifies the supervisor to restart a child node (and, if specified all its siblings as well) when the node fails in unexpected ways.
Since: 0.0.0
type SupervisorStartError ¶
type SupervisorStartError = s.SupervisorStartError
SupervisorStartError wraps an error reported on the initialization of a child node, enhancing it with supervisor information and possible termination errors on other siblings
Since: 0.0.0
type SupervisorTerminationError ¶
type SupervisorTerminationError = s.SupervisorTerminationError
SupervisorTerminationError wraps errors returned by a child node that failed to terminate (io errors, timeouts, etc.), enhancing it with supervisor information. Note, the only way to have a valid SupervisorTerminationError is for one of the child nodes to fail or the supervisor cleanup operation fails.
Since: 0.0.0