Around 增强点
节点环绕通知(Around Advice):在节点OnMsg方法执行之前和之后执行。该类型增强点,可以替换原节点逻辑。可以实现节点故障转移、重试、缓存等功能。
Before、After、Around Advice 执行顺序:Around->Before->Around
# 接口
// Order 返回执行顺序,值越小,优先级越高
Order() int
// 规则链初始化时候会调用该方法创建新的实例,如果字段值需要继承,在这里处理
New() Aspect
// PointCut 声明一个切入点,用于判断是否需要执行增强点
//例如:指定某些组件类型或者relationType才执行切面逻辑;return ctx.Self().Type()=="mqttClient"
PointCut(ctx RuleContext, msg RuleMsg, relationType string) bool
//Around 节点 OnMsg 方法执行环绕的增强点。
//如果返回false:引擎不会调用当前节点的OnMsg方法,需要Aspect手动触发,如:ctx.Self().OnMsg(ctx, msg),或者通过 ctx.TellNext(msg, relationType) 控制流程。
//如果返回true:引擎会调用当前节点的OnMsg方法。
Around(ctx RuleContext, msg RuleMsg, relationType string) (RuleMsg, bool)
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
Around msg返回值无法影响下一个节点入参,请用 before 切面或者通过 ctx.TellNext(msg, relationType) 控制。
# 示例
type AroundAspect struct {
Name string
}
func (aspect *AroundAspect) Order() int {
return 5
}
func (aspect *AroundAspect) New() types.Aspect {
return &AroundAspect{}
}
func (aspect *AroundAspect) PointCut(ctx types.RuleContext, msg types.RuleMsg, relationType string) bool {
return true
}
func (aspect *AroundAspect) Around(ctx types.RuleContext, msg types.RuleMsg, relationType string) (types.RuleMsg, bool) {
fmt.Printf("debug Around before ruleChainId:%s,flowType:%s,nodeId:%s,msg:%+v,relationType:%s \n", ctx.RuleChain().GetNodeId().Id, "Around", ctx.Self().GetNodeId().Id, msg, relationType)
msg.Metadata.PutValue(ctx.GetSelfId()+"_before", ctx.GetSelfId()+"_before")
// 执行当前节点逻辑
ctx.Self().OnMsg(ctx, msg)
//获取执行结果
//ctx.GetOut()
fmt.Printf("debug Around after ruleChainId:%s,flowType:%s,nodeId:%s,msg:%+v,relationType:%s \n", ctx.RuleChain().GetNodeId().Id, "Around", ctx.Self().GetNodeId().Id, msg, relationType)
//返回false,脱离框架不重复执行该节点逻辑
return msg, false
}
func TestAroundAspect(t *testing.T) {
var chain = `
{
"ruleChain": {
"id": "rule8848",
"name": "测试规则链",
"root": true
},
"metadata": {
"nodes": [
{
"id": "s1",
"type": "jsFilter",
"name": "过滤",
"debugMode": true,
"configuration": {
"jsScript": "return msg.role=='admin';"
}
},
{
"id": "s2",
"type": "jsTransform",
"name": "转换",
"debugMode": true,
"configuration": {
"jsScript": "msg.userName=msg.userName+'NO-1';\n return {'msg':msg,'metadata':metadata,'msgType':msgType};"
}
}
],
"connections": [
{
"fromId": "s1",
"toId": "s2",
"type": "False"
}
]
}
}
`
chainId := "test_around_aspect"
config := NewConfig()
ruleEngine, err := DefaultPool.New(chainId, []byte(chain), WithConfig(config), types.WithAspects(
&AroundAspect{Name: "AroundAspect1"},
))
if err != nil {
t.Error(err)
}
metaData := types.NewMetadata()
metaData.PutValue("productType", "test01")
msg := types.NewMsg(0, "TEST_MSG_TYPE1", types.JSON, metaData, "{\"temperature\":41}")
ruleEngine.OnMsg(msg)
time.Sleep(time.Millisecond * 200)
}
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
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
在 GitHub 上编辑此页 (opens new window)
上次更新: 2024/10/23, 10:13:01