-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
stop.go
74 lines (58 loc) · 1.46 KB
/
stop.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
package endure
import (
"context"
stderr "errors"
"reflect"
"sync"
"github.com/roadrunner-server/errors"
"go.uber.org/zap"
)
func (e *Endure) stop() error {
/*
topological order
*/
vertices := e.graph.TopologicalOrder()
if len(vertices) == 0 {
return errors.E(errors.Str("error occurred, nothing to run"))
}
mu := new(sync.Mutex)
errs := make([]error, 0, 2)
wg := &sync.WaitGroup{}
wg.Add(len(vertices))
// reverse order
for i := len(vertices) - 1; i >= 0; i-- {
if !vertices[i].IsActive() {
wg.Done()
continue
}
if !reflect.TypeOf(vertices[i].Plugin()).Implements(reflect.TypeOf((*Service)(nil)).Elem()) {
wg.Done()
continue
}
go func(i int) {
defer wg.Done()
stopMethod, _ := reflect.TypeOf(vertices[i].Plugin()).MethodByName(StopMethodName)
var inVals []reflect.Value
inVals = append(inVals, reflect.ValueOf(vertices[i].Plugin()))
e.log.Debug(
"calling stop function",
zap.String("plugin", vertices[i].ID().String()),
)
ctx, cancel := context.WithTimeout(context.Background(), e.stopTimeout)
inVals = append(inVals, reflect.ValueOf(ctx))
ret := stopMethod.Func.Call(inVals)[0].Interface()
if ret != nil {
e.log.Error("failed to stop the plugin", zap.String("name", vertices[i].ID().String()), zap.Error(ret.(error)))
mu.Lock()
errs = append(errs, ret.(error))
mu.Unlock()
}
cancel()
}(i)
}
wg.Wait()
if len(errs) > 0 {
return stderr.Join(errs...)
}
return nil
}