diff options
-rw-r--r-- | gonf/gonf.go | 8 | ||||
-rw-r--r-- | gonf/services.go | 96 |
2 files changed, 104 insertions, 0 deletions
diff --git a/gonf/gonf.go b/gonf/gonf.go index b5aec4f..363a227 100644 --- a/gonf/gonf.go +++ b/gonf/gonf.go @@ -31,6 +31,14 @@ func Resolve() (status Status) { packages_list_function() continue } + // ----- Services ---------------------------------------------- + status = resolveServices() + switch status { + case BROKEN: + return BROKEN + case REPAIRED: + continue + } // ----- Commands ---------------------------------------------- status = resolveCommands() switch status { diff --git a/gonf/services.go b/gonf/services.go new file mode 100644 index 0000000..58c7383 --- /dev/null +++ b/gonf/services.go @@ -0,0 +1,96 @@ +package gonf + +import "log/slog" + +// ----- Globals --------------------------------------------------------------- +var services []*ServicePromise + +// service management function +var serviceFunction func(string, string) (Status, error) + +// ----- Init ------------------------------------------------------------------ +func init() { + services = make([]*ServicePromise, 0) +} + +// ----- Public ---------------------------------------------------------------- +func SetServiceFunction(f func(string, string) (Status, error)) { + serviceFunction = f +} + +func Service(names ...string) *ServicePromise { + return &ServicePromise{ + chain: nil, + err: nil, + names: names, + states: nil, + status: PROMISED, + } +} + +func (s *ServicePromise) State(states ...string) *ServicePromise { + s.states = states + return s +} + +type ServicePromise struct { + chain []Promise + err error + names []string + states []string + status Status +} + +func (s *ServicePromise) IfRepaired(ps ...Promise) Promise { + s.chain = ps + return s +} + +func (s *ServicePromise) Promise() Promise { + services = append(services, s) + return s +} + +func (s *ServicePromise) Resolve() { + for _, name := range s.names { + var repaired = false + for _, state := range s.states { + s.status, s.err = serviceFunction(name, state) + if s.status == BROKEN { + slog.Error("service", "name", name, "state", state, "status", s.status, "error", s.err) + return + } else if s.status == REPAIRED { + repaired = true + } + } + if repaired { + s.status = REPAIRED + slog.Info("service", "name", name, "state", s.states, "status", s.status) + } else { + s.status = KEPT + slog.Debug("service", "name", name, "state", s.states, "status", s.status) + } + } + if s.status == REPAIRED { + for _, pp := range s.chain { + pp.Resolve() + } + } +} + +// ----- Internal -------------------------------------------------------------- +func resolveServices() (status Status) { + status = KEPT + for _, c := range services { + if c.status == PROMISED { + c.Resolve() + switch c.status { + case BROKEN: + return BROKEN + case REPAIRED: + status = REPAIRED + } + } + } + return +} |