camfish/run.go
2024-12-31 01:27:53 -05:00

125 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] 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