-
Notifications
You must be signed in to change notification settings - Fork 8
/
controller_pool.go
144 lines (128 loc) · 4.53 KB
/
controller_pool.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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package application
import (
"fmt"
"reflect"
"strings"
"sync"
"github.com/PolarPanda611/trinitygo/startup"
"github.com/gin-gonic/gin"
"github.com/kataras/golog"
)
// ControllerPool service pool
// if grpc string is the full method of method
// if http os the GET@/ping/:id
// need to filter controllerFuncMap to filter funcname
type ControllerPool struct {
mu sync.RWMutex
instanceMap map[string]reflect.Type
controllerMap []string
controllerFuncMap map[string]string
controllerValidators map[string][]Validator
}
// NewControllerPool new pool with init map
func NewControllerPool() *ControllerPool {
result := new(ControllerPool)
result.mu.Lock()
defer result.mu.Unlock()
result.instanceMap = make(map[string]reflect.Type)
result.controllerFuncMap = make(map[string]string)
result.controllerValidators = make(map[string][]Validator)
return result
}
// NewController add new service
func (s *ControllerPool) NewController(controllerType string, instance reflect.Type) {
s.mu.Lock()
defer s.mu.Unlock()
s.instanceMap[controllerType] = instance
s.controllerMap = append(s.controllerMap, controllerType)
}
// NewControllerFunc register funcname for controllertype
func (s *ControllerPool) NewControllerFunc(controllerType string, funcName string) {
s.mu.Lock()
defer s.mu.Unlock()
s.controllerFuncMap[controllerType] = funcName
}
// NewControllerValidators register funcname for controllertype
func (s *ControllerPool) NewControllerValidators(controllerType string, validator ...Validator) {
s.mu.Lock()
defer s.mu.Unlock()
s.controllerValidators[controllerType] = validator
}
// GetControllerMap get controller map
func (s *ControllerPool) GetControllerMap() []string {
s.mu.RLock()
defer s.mu.RUnlock()
return s.controllerMap
}
// ControllerFuncSelfCheck self check http request registered func exist or not
func (s *ControllerPool) ControllerFuncSelfCheck(instancePool *InstancePool, isLog bool, logger *golog.Logger) {
s.mu.RLock()
defer s.mu.RUnlock()
for controllerName, instanceName := range s.instanceMap {
controllerNameDecode := strings.Split(controllerName, "@")
if len(controllerNameDecode) == 1 {
// GRPC
return
}
funcName, funcExist := s.controllerFuncMap[controllerName]
if funcName == "" || !funcExist {
funcName = controllerNameDecode[0]
// func not exist
logger.Fatalf("booting self func checking controller %v , no func registered , self check failed ...", controllerName)
}
pool, ok := instancePool.poolMap[instanceName]
if !ok {
// func not exist
logger.Fatalf("booting self func checking controller %v , no instance %v registered , self check failed ...", controllerName, instanceName)
}
instance := pool.Get()
defer pool.Put(instance)
m, funcImpled := reflect.TypeOf(instance).MethodByName(funcName)
if !funcImpled {
logger.Fatalf("booting self func checking controller %v , func %v not registered , self check failed ...", controllerName, funcName)
}
if isLog {
startup.AppendStartupDebuggerInfo(fmt.Sprintf("booting self func checking controller %v , func %v checked ", controllerName, funcName))
}
if m.Type.NumIn() < -1 {
logger.Fatalf("booting self func checking controller %v , func %v should have at least 1 in args , self check failed ...", controllerName, funcName)
}
if m.Type.NumOut() > 2 {
logger.Fatalf("booting self func checking controller %v , func %v should have at most 2 out args , self check failed ...", controllerName, funcName)
}
}
return
}
// GetController from pool
func (s *ControllerPool) GetController(controllerName string, tctx Context, app Application, c *gin.Context) (interface{}, map[reflect.Type]interface{}, map[reflect.Type]interface{}) {
s.mu.RLock()
instanceName, ok := s.instanceMap[controllerName]
s.mu.RUnlock()
if !ok {
panic(fmt.Sprintf("unknown controller name : %v", controllerName))
}
return app.InstancePool().GetInstance(instanceName, tctx, app, c)
}
// GetControllerFuncName get controller func name
func (s *ControllerPool) GetControllerFuncName(controllerName string) (string, bool) {
s.mu.RLock()
defer s.mu.RUnlock()
if len(s.controllerFuncMap) == 0 {
return "", false
}
funcName, ok := s.controllerFuncMap[controllerName]
return funcName, ok
}
// GetControllerValidators get controller func name
func (s *ControllerPool) GetControllerValidators(controllerName string) []Validator {
s.mu.RLock()
defer s.mu.RUnlock()
if len(s.controllerValidators) == 0 {
return nil
}
validators, ok := s.controllerValidators[controllerName]
if !ok {
return nil
}
return validators
}