1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
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(p ...Promise) Promise {
s.chain = append(s.chain, p...)
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()
}
}
}
func (s ServicePromise) Status() Status {
return s.status
}
// ----- 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
}
|