126 lines
5.9 KiB
Go
126 lines
5.9 KiB
Go
package camfish
|
|
|
|
import "iter"
|
|
import "context"
|
|
|
|
var env environment
|
|
|
|
// Run runs the daemon given the slice of actors, and shuts down the program
|
|
// when all running actors have stopped. Error and log messages will be printed.
|
|
// The correct way to use this function is to have it be the only thing in main:
|
|
//
|
|
// func main() {
|
|
// camfish.Run("name", "what it does", new(SomeActor), new(AnotherActor))
|
|
// }
|
|
//
|
|
// Run operates in several phases. In each phase that involves actors, the
|
|
// actors are operated on in the order they are specified in the variadic actors
|
|
// argument. This as well as the order of the phases is considered part of the
|
|
// API and are stable for versions above v1.0.0, but some exact details such as
|
|
// timing are not and may change in the future. The phases are as follows:
|
|
//
|
|
// 10. Flag parsing: Actors which implement [FlagAdder] are given an object
|
|
// which will allow them to add command line flags. Actors are given the
|
|
// object one after the other in the order that they are specified in the
|
|
// vararg list for Run. The flags are then parsed, giving values to the
|
|
// actors that requested them.
|
|
//
|
|
// 20. Log switching: The environment begins redirecting all logging output to
|
|
// a file if specified in the flags. After Run exits, logging will be
|
|
// redirected back to [os.Stderr].
|
|
//
|
|
// 30. Configuration parsing: The configuration file is parsed. If a specific
|
|
// file was not specified by a flag, it is loaded from
|
|
// /etc/<name>/<name>.conf
|
|
//
|
|
// 40. Configuration processing: Actors which implement [ConfigProcessor] are
|
|
// given a MutableConfig to read and modify. Actors are given the config
|
|
// one after the other in the order that they are specified in the vararg
|
|
// list for Run. Actors can use flag values they have received to override
|
|
// config values, apply macros, etc.
|
|
//
|
|
// 50. Configuration application: Actors which implement [Configurable] are
|
|
// given a [Config] to read. The order is not guaranteed.
|
|
//
|
|
// 60. Initialization: Actors which implement [Initializable] are initialized
|
|
// in parallel. During this time, actors may do things like establish
|
|
// network connections, start up servers, initialize data structures, etc.
|
|
// Actors may establish references to each-other during this time, but
|
|
// they must not interact yet. The amount of time actors have to do this
|
|
// is configurable, but by default it is 8 minutes. The vast majority of
|
|
// actors should initialize in under 100 milliseconds.
|
|
//
|
|
// 70. Running: Actors which implement [Runnable] or [RunShutdownable] are
|
|
// run, each in their own goroutine. The environment is able to restart
|
|
// actors which have failed, which entails resetting the actor if it
|
|
// implements [Resettable], and running the actor again within the same
|
|
// goroutine. If an actor does not run for a meaningful amount of time
|
|
// after resetting/initialization before failing, it is considered erratic
|
|
// and further attempts to restart it will be spaced by a limited,
|
|
// constantly increasing time interval. The timing is configurable, but by
|
|
// default the threshold for a meaningful amount of runtime is 16 seconds,
|
|
// the initial delay interval is 8 seconds, the interval increase per
|
|
// attempt is 8 seconds, and the maximum interval is one hour.
|
|
// Additionally, programs which implement [Trimmable] will be trimmed
|
|
// regularly whenever they are running. The trimming interval is also
|
|
// configurable, but by default it is once every minute. When an actor
|
|
// which implements [Resettable] is reset, it is given a configurable
|
|
// timeout, which is 8 minutes by default.
|
|
//
|
|
// 80. Shutdown: This can be triggered by all actors being removed from the
|
|
// environment, a catastrophic error, [Done] being called, or the program
|
|
// recieving SIGINT. If necessary, the environment shuts down all running
|
|
// actors and waits for them to stop. If they do not all stop in time, an
|
|
// error message is printed and the program will exit with a non-zero code.
|
|
// Otherwise, it will exit with a code of 0. The amount of time actors
|
|
// have to shut down is configurable, but by default it is 8 minutes.
|
|
func Run(name, description string, actors ...Actor) {
|
|
env.Run(name, description, actors...)
|
|
}
|
|
|
|
// Done sends a shutdown signal to the environment with the given "cause" error.
|
|
// This will be logged as the reason for the shutdown.
|
|
func Done(cause error) {
|
|
env.Done(cause)
|
|
}
|
|
|
|
// Add adds an actor to the environment, starting it if necessary. If the
|
|
// environment is not running, it does nothing. Note that this function will
|
|
// block the current goroutine while the actors are initializing.
|
|
func Add(ctx context.Context, actors ...Actor) error {
|
|
return env.Add(ctx, actors...)
|
|
}
|
|
|
|
// Del removes an actor from the environment, stopping it if necessary. If the
|
|
// environment is not running, it does nothing. Note that this function will
|
|
// block the current goroutine while the actors are shutting down.
|
|
func Del(ctx context.Context, actors ...Actor) error {
|
|
return env.Del(ctx , actors...)
|
|
}
|
|
|
|
// Find finds an actor in the environment with the given type name. If no actor
|
|
// is found or the environment is not running, it returns nil.
|
|
func Find(typ string) Actor {
|
|
return env.Find(typ)
|
|
}
|
|
|
|
// FindAll returns an iterator over all actors in the environment with the given
|
|
// type name. If the environment is not running, it returns an empty iterator.
|
|
func FindAll(typ string) iter.Seq[Actor] {
|
|
return env.FindAll(typ)
|
|
}
|
|
|
|
// All returns an iterator over all actors in the environment. If the
|
|
// environment is not running, it returns an empty iterator.
|
|
func All() iter.Seq[Actor] {
|
|
return env.All()
|
|
}
|
|
|
|
// Verb returns true if verbose output is permitted. Actors should log less
|
|
// information when this is false.
|
|
func Verb() bool {
|
|
return env.Verb()
|
|
}
|
|
|
|
// tell me how tf its snowiung outside if its 33° f
|