-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathservice.go
157 lines (132 loc) · 3.31 KB
/
service.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
145
146
147
148
149
150
151
152
153
154
155
156
157
package dag
import (
"context"
"fmt"
"reflect"
)
// IService 执行器
type IService interface {
execute(ctx context.Context, dag *FxDag) error
getDependence() []string
}
// service 用于记录依赖关系
type service struct {
dependence map[string]struct{} // 依赖的参数
fn any
produce string // 产生的结果类型
pd bool // 是否提供依赖
}
// newService 创建一个新的服务
func newService(fn any, dependence map[string]struct{}, produce string, pd bool) *service {
return &service{
dependence: dependence,
fn: fn,
produce: produce,
pd: pd,
}
}
func (s *service) execute(ctx context.Context, dag *FxDag) error {
_, ok := s.fn.(reflect.Value)
if ok {
return s.executeReflect(ctx, dag)
}
_, ok = s.fn.(FxHandler[any])
if ok {
return s.executeHandler(ctx, dag)
}
return fmt.Errorf("fn is not supported")
}
func (s *service) getDependence() []string {
d := make([]string, 0, len(s.dependence))
for k := range s.dependence {
d = append(d, k)
}
return d
}
// executeHandler 用于执行handler
func (s *service) executeHandler(ctx context.Context, dag *FxDag) error {
_fn, ok := s.fn.(FxHandler[any])
if !ok {
return fmt.Errorf("fn is not of type FxHandler")
}
v, err := _fn(ctx, dag)
if err != nil {
return err
}
if !s.pd {
return nil
}
return dag.val.set(s.produce, v)
}
// executeReflect 用于执行反射函数
func (s *service) executeReflect(ctx context.Context, dag *FxDag) error {
_f, ok := s.fn.(reflect.Value)
if !ok {
return fmt.Errorf("fn is not of type reflect.Func")
}
fType := _f.Type()
params := make([]reflect.Value, 0, fType.NumIn())
params = append(params, reflect.ValueOf(ctx))
if fType.NumIn() > 1 {
for i := 1; i < fType.NumIn(); i++ {
if v, ok := dag.getVal(fType.In(i).String()); ok {
params = append(params, reflect.ValueOf(v))
}
}
}
// 调用函数
result := _f.Call(params)
// 无返回数据以及标记为不需要提供依赖
if fType.NumOut() == 0 || !s.pd {
return nil
}
// 检测最后一个参数是否是error
if fType.NumOut() > 0 {
callErr, ok := result[fType.NumOut()-1].Interface().(error)
if !ok && callErr != nil {
return fmt.Errorf("fn %s last return params must return a error", s.produce)
}
if callErr != nil {
return callErr
}
}
// 取第一个值作为提供项,只有一个返回参数时必须为error类型
if fType.NumOut() > 1 {
dag.setVal(s.produce, result[0].Interface())
}
return nil
}
// serviceT 用于记录依赖关系
type serviceT[T any] struct {
dependence map[string]struct{} // 依赖的参数
fn FxHandler[T]
produce string // 产生的结果类型
pd bool // 是否提供依赖
}
// newServiceT 创建一个新的服务
func newServiceT[T any](fn FxHandler[T], dependence map[string]struct{}, produce string, pd bool) *serviceT[T] {
s := serviceT[T]{
dependence: dependence,
fn: fn,
produce: produce,
pd: pd,
}
return &s
}
func (s *serviceT[T]) execute(ctx context.Context, dag *FxDag) error {
v, err := s.fn(ctx, dag)
if err != nil {
return err
}
if !s.pd {
return nil
}
return dag.val.set(s.produce, v)
}
func (s *serviceT[T]) getDependence() []string {
d := make([]string, 0, len(s.dependence))
for k := range s.dependence {
d = append(d, k)
}
return d
}