summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gonf/gonf.go8
-rw-r--r--gonf/services.go96
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
+}