Skip to content

Commit 2bbcb25

Browse files
committed
## 0.2.0-beta12 -> 调整action.Hook
1 parent 48e52ed commit 2bbcb25

20 files changed

+361
-171
lines changed

action/action.go

+37-37
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ type Action struct {
4242

4343
NewQuery func(ctx context.Context, req model.Map) *query.Query
4444
NewAction func(ctx context.Context, method string, req model.Map) *Action
45+
46+
HooksMap map[string][]*Hook
4547
}
4648

4749
func New(ctx context.Context, actionConfig *config.ActionConfig, method string, req model.Map) *Action {
@@ -127,58 +129,56 @@ func (a *Action) Result() (model.Map, error) {
127129

128130
for _, k := range a.tagRequest.ExecQueue {
129131
node := a.children[k]
130-
err = EmitHook(a.ctx, BeforeNodeExec, node, a.method)
131-
if err != nil {
132-
return nil, err
133-
}
134-
}
135-
136-
for _, k := range a.tagRequest.ExecQueue {
137132

138-
node := a.children[k]
139-
err = node.reqUpdate()
140-
if err != nil {
141-
return nil, err
133+
actionHookReq := &HookReq{
134+
Node: node,
135+
Method: a.method,
136+
ctx: a.ctx,
137+
nextIdx: -1,
138+
isInTransaction: false,
139+
hooks: getHooksByAccessName(a.HooksMap, k),
142140
}
143-
}
144-
145-
transactionHandler := noTransactionHandler
146141

147-
if a.tagRequest.Transaction != nil && *a.tagRequest.Transaction == true {
148-
h := GetTransactionHandler(a.ctx, a)
149-
if h == nil {
150-
err = consts.NewSysErr("transaction handler is nil")
151-
return nil, err
152-
}
142+
actionHookReq.handler = func(ctx context.Context, n *Node, method string) error {
143+
transactionHandler := noTransactionHandler
153144

154-
transactionHandler = h
145+
if a.tagRequest.Transaction != nil && *a.tagRequest.Transaction == true {
146+
h := GetTransactionHandler(a.ctx, a)
147+
if h == nil {
148+
err = consts.NewSysErr("transaction handler is nil")
149+
return err
150+
}
155151

156-
}
152+
transactionHandler = h
157153

158-
err = transactionHandler(a.ctx, func(ctx context.Context) error {
159-
for _, k := range a.tagRequest.ExecQueue {
160-
node := a.children[k]
161-
ret[k], err = node.execute(ctx, a.method)
162-
if err != nil {
163-
return err
164154
}
155+
156+
err = transactionHandler(a.ctx, func(ctx context.Context) error {
157+
for _, k := range a.tagRequest.ExecQueue {
158+
node := a.children[k]
159+
ret[k], err = node.execute(ctx, a.method)
160+
if err != nil {
161+
return err
162+
}
163+
}
164+
return nil
165+
})
166+
167+
return err
165168
}
166-
return nil
167-
})
168169

169-
if err != nil {
170-
return nil, err
171-
}
170+
err = node.reqUpdate()
171+
if err != nil {
172+
return nil, err
173+
}
172174

173-
for _, k := range a.tagRequest.ExecQueue {
174-
node := a.children[k]
175-
err = EmitHook(a.ctx, AfterNodeExec, node, a.method)
175+
err := actionHookReq.Next()
176176
if err != nil {
177177
return nil, err
178178
}
179179
}
180180

181-
return ret, err
181+
return ret, nil
182182
}
183183

184184
func checkTag(req model.Map, method string, requestCfg *config.ActionConfig) (*config.RequestConfig, error) {

action/hook.go

+121-41
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,136 @@
11
package action
22

3-
import "context"
4-
5-
const (
6-
BeforeNodeExec = iota
7-
AfterNodeExec
8-
BeforeExecutorDo
9-
AfterExecutorDo
3+
import (
4+
"context"
5+
"net/http"
106
)
117

12-
type Hook struct {
13-
For []string //
14-
// Exec 事务外
15-
BeforeNodeExec func(ctx context.Context, n *Node, method string) error
16-
AfterNodeExec func(ctx context.Context, n *Node, method string) error
17-
18-
// Do 事务内
19-
BeforeExecutorDo func(ctx context.Context, n *Node, method string) error
20-
AfterExecutorDo func(ctx context.Context, n *Node, method string) error
8+
// const (
9+
// BeforeNodeExec = iota
10+
// AfterNodeExec
11+
// BeforeExecutorDo
12+
// AfterExecutorDo
13+
// )
14+
15+
type HookReq struct {
16+
Node *Node
17+
Method string
18+
ctx context.Context
19+
hooks []*Hook
20+
nextIdx int
21+
isInTransaction bool
22+
handler finishHandler
2123
}
2224

23-
var hooksMap = map[string][]Hook{}
25+
func (r *HookReq) IsPost() bool {
26+
return r.Method == http.MethodPost
27+
}
2428

25-
func RegHook(h Hook) {
26-
for _, item := range h.For {
27-
hooksMap[item] = append(hooksMap[item], h)
28-
}
29+
func (r *HookReq) IsPut() bool {
30+
return r.Method == http.MethodPut
31+
}
32+
33+
func (r *HookReq) IsDelete() bool {
34+
return r.Method == http.MethodDelete
2935
}
3036

31-
func EmitHook(ctx context.Context, hookAt int, node *Node, method string) error {
32-
33-
hooks := append(hooksMap["*"], hooksMap[node.Key]...)
34-
for _, hook := range hooks {
35-
36-
var handler func(ctx context.Context, n *Node, method string) error
37-
switch hookAt {
38-
case BeforeNodeExec:
39-
handler = hook.BeforeNodeExec
40-
case AfterNodeExec:
41-
handler = hook.AfterNodeExec
42-
case BeforeExecutorDo:
43-
handler = hook.BeforeExecutorDo
44-
case AfterExecutorDo:
45-
handler = hook.AfterExecutorDo
37+
func (r *HookReq) Next() error {
38+
39+
for {
40+
41+
var h *Hook
42+
43+
for r.nextIdx < len(r.hooks) && h == nil {
44+
45+
if r.nextIdx+1 >= len(r.hooks) {
46+
if r.isInTransaction {
47+
// finish all
48+
return r.handler(r.ctx, r.Node, r.Method)
49+
} else {
50+
r.nextIdx = -1
51+
r.isInTransaction = true
52+
}
53+
}
54+
55+
r.nextIdx++
56+
57+
_h := r.hooks[r.nextIdx]
58+
59+
if r.isInTransaction {
60+
if _h.HandlerInTransaction == nil {
61+
continue
62+
}
63+
h = _h
64+
} else {
65+
if _h.Handler == nil {
66+
continue
67+
}
68+
h = _h
69+
}
70+
4671
}
4772

48-
if handler != nil {
49-
err := handler(ctx, node, method)
50-
if err != nil {
51-
return err
73+
if r.nextIdx < len(r.hooks) {
74+
if r.isInTransaction {
75+
return h.HandlerInTransaction(r.ctx, r)
5276
}
77+
78+
return h.Handler(r.ctx, r)
5379
}
5480
}
55-
return nil
81+
5682
}
83+
84+
type Hook struct {
85+
For []string
86+
// 事务外 , 可执行参数校验,io等耗时操作
87+
Handler func(ctx context.Context, req *HookReq) error
88+
// 事务内,尽量少执行耗时操作 (无论request配置中是否开启事务, 都会先执行handler 然后 在范围内执行HandlerInTransaction)
89+
HandlerInTransaction func(ctx context.Context, req *HookReq) error
90+
}
91+
92+
type finishHandler func(ctx context.Context, n *Node, method string) error
93+
94+
func getHooksByAccessName(hooksMap map[string][]*Hook, accessName string) []*Hook {
95+
hooks := append(hooksMap["*"], hooksMap[accessName]...)
96+
return hooks
97+
}
98+
99+
//
100+
// type Hook2 struct {
101+
// For []string //
102+
// // Exec 事务外
103+
// BeforeNodeExec func(ctx context.Context, n *Node, method string) error
104+
// AfterNodeExec func(ctx context.Context, n *Node, method string) error
105+
//
106+
// // Do 事务内
107+
// BeforeExecutorDo func(ctx context.Context, n *Node, method string) error
108+
// AfterExecutorDo func(ctx context.Context, n *Node, method string) error
109+
// }
110+
//
111+
// func emitHook(ctx context.Context, hooksMap map[string][]Hook, hookAt int, node *Node, method string) error {
112+
//
113+
// hooks := append(hooksMap["*"], hooksMap[node.Key]...)
114+
// for _, hook := range hooks {
115+
//
116+
// var handler func(ctx context.Context, n *Node, method string) error
117+
// switch hookAt {
118+
// case BeforeNodeExec:
119+
// handler = hook.BeforeNodeExec
120+
// case AfterNodeExec:
121+
// handler = hook.AfterNodeExec
122+
// case BeforeExecutorDo:
123+
// handler = hook.BeforeExecutorDo
124+
// case AfterExecutorDo:
125+
// handler = hook.AfterExecutorDo
126+
// }
127+
//
128+
// if handler != nil {
129+
// err := handler(ctx, node, method)
130+
// if err != nil {
131+
// return err
132+
// }
133+
// }
134+
// }
135+
// return nil
136+
// }

action/node.go

+4-14
Original file line numberDiff line numberDiff line change
@@ -264,11 +264,11 @@ func (n *Node) reqUpdate() error {
264264

265265
// call functions
266266
{
267-
queryConfig := n.Action.ActionConfig
267+
actionConfig := n.Action.ActionConfig
268268

269269
functionName, paramKeys := util.ParseFunctionsStr(updateVal.(string))
270270

271-
_func := queryConfig.Func(functionName)
271+
_func := actionConfig.Func(functionName)
272272

273273
param := model.Map{}
274274
for paramI, item := range _func.ParamList {
@@ -279,7 +279,7 @@ func (n *Node) reqUpdate() error {
279279
}
280280
}
281281

282-
val, err := _func.Handler(n.ctx, param)
282+
val, err := actionConfig.CallFunc(n.ctx, functionName, param)
283283
if err != nil {
284284
return err
285285
}
@@ -327,11 +327,6 @@ func (n *Node) reqUpdateBeforeDo() error {
327327

328328
func (n *Node) do(ctx context.Context, method string) (ret model.Map, err error) {
329329

330-
err = EmitHook(ctx, BeforeExecutorDo, n, method)
331-
if err != nil {
332-
return nil, err
333-
}
334-
335330
var rowKeyVal model.Map
336331
var rowKey string
337332

@@ -346,7 +341,7 @@ func (n *Node) do(ctx context.Context, method string) (ret model.Map, err error)
346341
if access.RowKeyGen != "" {
347342
for i, _ := range n.Data {
348343

349-
rowKeyVal, err = n.Action.ActionConfig.RowKeyGen(ctx, access.RowKeyGen, n.Key, n.Data[i])
344+
rowKeyVal, err = n.Action.ActionConfig.RowKeyGen(ctx, access.RowKeyGen, n.Key, n.tableName, n.Data[i])
350345
if err != nil {
351346
return nil, err
352347
}
@@ -406,11 +401,6 @@ func (n *Node) do(ctx context.Context, method string) (ret model.Map, err error)
406401

407402
n.Ret = ret
408403

409-
err = EmitHook(ctx, AfterExecutorDo, n, method)
410-
if err != nil {
411-
return nil, err
412-
}
413-
414404
return
415405
}
416406

apijson.go

+14
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ type ApiJson struct {
1717
config *config.Config
1818
Debug bool // 是否开启debug模式, 显示每步骤
1919
ctx context.Context
20+
21+
actionHooks []action.Hook
22+
actionHookMap map[string][]*action.Hook
2023
}
2124

2225
var DefaultApiJson = New()
@@ -76,5 +79,16 @@ func (a *ApiJson) NewAction(ctx context.Context, method string, req model.Map) *
7679

7780
act.NewQuery = a.NewQuery
7881

82+
act.HooksMap = a.actionHookMap
83+
7984
return act
8085
}
86+
87+
func (a *ApiJson) RegActionHook(hook action.Hook) {
88+
if a.actionHookMap == nil {
89+
a.actionHookMap = make(map[string][]*action.Hook)
90+
}
91+
for _, item := range hook.For {
92+
a.actionHookMap[item] = append(a.actionHookMap[item], &hook)
93+
}
94+
}

0 commit comments

Comments
 (0)