-
Notifications
You must be signed in to change notification settings - Fork 8
/
instance_pool.go
104 lines (91 loc) · 2.82 KB
/
instance_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
package application
import (
"reflect"
"sync"
"github.com/gin-gonic/gin"
)
// InstancePool service pool
type InstancePool struct {
// map[instanceName] = instancePool
poolMap map[reflect.Type]*sync.Pool
// instance list
instanceTypeList []reflect.Type
// instance tags maps instanceName
poolTags map[string]reflect.Type
// instanceMapping instance mapping
// caching the instance di instance relation during the self check
instanceMapping map[string]reflect.Type
}
// NewInstancePool new pool with init map
func NewInstancePool() *InstancePool {
result := new(InstancePool)
result.poolMap = make(map[reflect.Type]*sync.Pool)
result.poolTags = make(map[string]reflect.Type)
result.instanceMapping = make(map[string]reflect.Type)
return result
}
// NewInstance add new instance
func (s *InstancePool) NewInstance(instanceType reflect.Type, instancePool *sync.Pool, instanceTags []string) {
if _, ok := s.poolMap[instanceType]; ok {
return
}
s.poolMap[instanceType] = instancePool
s.instanceTypeList = append(s.instanceTypeList, instanceType)
if len(instanceTags) > 0 {
if instanceTags[0] != "" {
s.poolTags[instanceTags[0]] = instanceType
}
}
}
// GetInstanceType get all service type
func (s *InstancePool) GetInstanceType(tags string) []reflect.Type {
if tags != "" {
var types []reflect.Type
if instance, ok := s.poolTags[tags]; ok {
types = append(types, instance)
return types
}
return types
}
return s.instanceTypeList
}
// CheckInstanceNameIfExist check contain name if exist
func (s *InstancePool) CheckInstanceNameIfExist(instanceName reflect.Type) bool {
_, ok := s.poolMap[instanceName]
return ok
}
// InstanceDISelfCheck self check di request registered func exist or not
func (s *InstancePool) InstanceDISelfCheck(app Application) {
for instanceType, pool := range s.poolMap {
DiSelfCheck(instanceType, pool, app.Logger(), app.InstancePool(), s.instanceMapping)
}
return
}
// GetInstance get service with di
func (s *InstancePool) GetInstance(instanceType reflect.Type, tctx Context, app Application, c *gin.Context) (interface{}, map[reflect.Type]interface{}, map[reflect.Type]interface{}) {
pool, ok := s.poolMap[instanceType]
if !ok {
panic("unknown service name")
}
service := pool.Get()
sharedInstance, toFreeInstance := DiAllFields(service, tctx, app, c, s.InstanceMapping())
return service, sharedInstance, toFreeInstance
}
// InstanceMapping instance mapping
func (s *InstancePool) InstanceMapping() map[string]reflect.Type {
instanceMap := make(map[string]reflect.Type, len(s.instanceMapping))
for k, v := range s.instanceMapping {
instanceMap[k] = v
}
return instanceMap
}
// Release release service
func (s *InstancePool) Release(instance interface{}) {
t := reflect.TypeOf(instance)
syncpool, ok := s.poolMap[t]
if !ok {
return
}
DiFree(instance)
syncpool.Put(instance)
}