forked from lucaslorentz/caddy-supervisor
/
setup.go
117 lines (94 loc) · 2.27 KB
/
setup.go
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package servertype
import (
"strings"
"sync"
"github.com/lucaslorentz/caddy-supervisor/supervisor"
"github.com/mholt/caddy"
"github.com/mholt/caddy/caddyfile"
)
func init() {
var directives = []string{
"command",
"args",
"dir",
"redirect_stdout",
"redirect_stderr",
"restart_policy",
"termination_grace_period",
"env",
}
caddy.RegisterServerType("supervisor", caddy.ServerType{
Directives: func() []string {
return directives
},
NewContext: newContext,
})
for _, directive := range directives {
caddy.RegisterPlugin(directive, caddy.Plugin{
ServerType: "supervisor",
Action: setup,
})
}
}
func newContext(inst *caddy.Instance) caddy.Context {
return &supervisorContext{
instance: inst,
options: make(map[string]*supervisor.Options),
}
}
type supervisorContext struct {
instance *caddy.Instance
options map[string]*supervisor.Options
}
func (n *supervisorContext) InspectServerBlocks(sourceFile string, serverBlocks []caddyfile.ServerBlock) ([]caddyfile.ServerBlock, error) {
for _, sb := range serverBlocks {
key := mergeKeys(sb.Keys)
n.options[key] = supervisor.CreateOptions()
}
return serverBlocks, nil
}
var supervisors []*supervisor.Supervisor
// MakeServers uses the newly-created configs to create and return a list of server instances.
func (n *supervisorContext) MakeServers() ([]caddy.Server, error) {
for _, options := range n.options {
supervisor := supervisor.CreateSupervisor(options)
supervisors = append(supervisors, supervisor)
supervisor.Start()
}
return nil, nil
}
func setup(c *caddy.Controller) error {
key := mergeKeys(c.ServerBlockKeys)
ctx := c.Context().(*supervisorContext)
setupEventsOnlyOnce(c)
return c.OncePerServerBlock(func() error {
options := ctx.options[key]
for c.Next() {
supervisor.ParseOption(c, options)
}
return nil
})
}
func mergeKeys(keys []string) string {
return strings.Join(keys, " ")
}
var didSetupEvents = false
func setupEventsOnlyOnce(c *caddy.Controller) {
if didSetupEvents {
return
}
c.OnShutdown(shutdownSupervisors)
didSetupEvents = true
}
func shutdownSupervisors() error {
var wg sync.WaitGroup
for _, s := range supervisors {
wg.Add(1)
go func(s *supervisor.Supervisor) {
defer wg.Done()
s.Stop()
}(s)
}
wg.Wait()
return nil
}