forked from zeromicro/go-zero
-
Notifications
You must be signed in to change notification settings - Fork 0
/
servicegroup.go
117 lines (95 loc) · 2.03 KB
/
servicegroup.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 service
import (
"log"
"github.com/tal-tech/go-zero/core/proc"
"github.com/tal-tech/go-zero/core/syncx"
"github.com/tal-tech/go-zero/core/threading"
)
type (
// Starter is the interface wraps the Start method.
Starter interface {
Start()
}
// Stopper is the interface wraps the Stop method.
Stopper interface {
Stop()
}
// Service is the interface that groups Start and Stop methods.
Service interface {
Starter
Stopper
}
// A ServiceGroup is a group of services.
ServiceGroup struct {
services []Service
stopOnce func()
}
)
// NewServiceGroup returns a ServiceGroup.
func NewServiceGroup() *ServiceGroup {
sg := new(ServiceGroup)
sg.stopOnce = syncx.Once(sg.doStop)
return sg
}
// Add adds service into sg.
func (sg *ServiceGroup) Add(service Service) {
sg.services = append(sg.services, service)
}
// Start starts the ServiceGroup.
// There should not be any logic code after calling this method, because this method is a blocking one.
// Also, quitting this method will close the logx output.
func (sg *ServiceGroup) Start() {
proc.AddShutdownListener(func() {
log.Println("Shutting down...")
sg.stopOnce()
})
sg.doStart()
}
// Stop stops the ServiceGroup.
func (sg *ServiceGroup) Stop() {
sg.stopOnce()
}
func (sg *ServiceGroup) doStart() {
routineGroup := threading.NewRoutineGroup()
for i := range sg.services {
service := sg.services[i]
routineGroup.RunSafe(func() {
service.Start()
})
}
routineGroup.Wait()
}
func (sg *ServiceGroup) doStop() {
for _, service := range sg.services {
service.Stop()
}
}
// WithStart wraps a start func as a Service.
func WithStart(start func()) Service {
return startOnlyService{
start: start,
}
}
// WithStarter wraps a Starter as a Service.
func WithStarter(start Starter) Service {
return starterOnlyService{
Starter: start,
}
}
type (
stopper struct {
}
startOnlyService struct {
start func()
stopper
}
starterOnlyService struct {
Starter
stopper
}
)
func (s stopper) Stop() {
}
func (s startOnlyService) Start() {
s.start()
}