This repository has been archived by the owner on May 5, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
group.go
70 lines (60 loc) · 1.71 KB
/
group.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
package supervisor
import (
"context"
"sync"
)
// Group is a superset of Supervisor datastructure responsible for offering a
// supervisor tree whose all services are restarted whenever one of them fail or
// is restarted. It assumes that all services rely on each other. It does not
// guarantee any start other, but it does guarantee all services will be
// restarted. It implements Service, therefore it can be nested if necessary
// either with other Group or Supervisor. When passing the Group around,
// remind to do it as reference (&supervisor).
type Group struct {
*Supervisor
}
// Serve starts the Group tree. It can be started only once at a time. If
// stopped (canceled), it can be restarted. In case of concurrent calls, it will
// hang until the current call is completed.
func (g *Group) Serve(ctx context.Context) {
if g.Supervisor == nil {
panic("Supervisor missing for this Group.")
}
g.Supervisor.prepare()
restartCtx, cancel := context.WithCancel(ctx)
var (
mu sync.Mutex
processingFailure bool
)
processFailure := func() {
mu.Lock()
if processingFailure {
mu.Unlock()
return
}
processingFailure = true
mu.Unlock()
if !g.shouldRestart() {
cancel()
return
}
g.mu.Lock()
g.Log("halting all services after failure")
for _, c := range g.terminations {
c()
}
g.cancelations = make(map[string]context.CancelFunc)
g.mu.Unlock()
go func() {
g.Log("waiting for all services termination")
g.runningServices.Wait()
g.Log("waiting for all services termination - completed")
mu.Lock()
processingFailure = false
mu.Unlock()
g.Log("triggering group restart")
g.added <- struct{}{}
}()
}
serve(g.Supervisor, restartCtx, processFailure)
}