hyperjumptech/grule-rule-engine

map类型的key赋值后,下一个循环中并没有检测到有新key加入

chestarss opened this issue · 2 comments

Describe the bug
A clear and concise description of what the bug is.

{1 资源使用分 true u 0001-01-01 00:00:00 +0000 UTC 2024-01-18 21:43:03.812 +0800 CST}
&{false 1 0 map[limits:2 requests:1 usage:1.4] map[]}

HasKey A
HasKey B
ERRO[0000] Max cycle reached lib=grule-rule-engine package=engine
Error executing rules: the GruleEngine successfully selected rule candidate for execution after 100 cycles, this could possibly caused by rule entry(s) that keep added into execution pool but when executed it does not change any data in context. Please evaluate your rule entries "When" and "Then" scope. You can adjust the maximum cycle using GruleEngine.MaxCycle variable
{false 1 0 map[limits:2 requests:1 usage:1.4] map[A:0.7 B:1.4]}

To Reproduce
Steps to reproduce the behavior:

  1. I create code for this and that
type AppItemParam struct {
	Status    bool
	AppId     int32
	Score     int
	MetricMap map[string]interface{}
	// 用于规则引擎存储中间结果
	MiddleResult map[string]interface{}
}

func (a *AppItemParam) HasKey(key string) bool {
	fmt.Println("HasKey", key)
	if _, ok := a.MiddleResult[key]; ok {
		return true
	}
	return false
}

// init fact
                metricMap := make(map[string]interface{})
		metricMap["requests"] = 1
		metricMap["limits"] = 2
		metricMap["usage"] = 1.4
		param := score.AppItemParam{
			AppId:        1,
			Score:        0,
			MetricMap:    metricMap,
			MiddleResult: make(map[string]interface{}),
			Status:       false,
		}


// run rule
// 创建规则引擎
	lib := ast.NewKnowledgeLibrary()
	ruleBuilder := builder.NewRuleBuilder(lib)

	// 加载规则文件
	err := ruleBuilder.BuildRuleFromResource("Test", "0.1.1", pkg.NewFileResource("rules/a1.grl"))
	if err != nil {
		fmt.Println("Error loading rules:", err)
		return
	}

	// 创建规则引擎上下文
	kb, err := lib.NewKnowledgeBaseInstance("Test", "0.1.1")
	fmt.Println(err)

	dataContext := ast.NewDataContext()
	dataContext.Add("F", param)

	// 执行规则
	engine := &engine.GruleEngine{MaxCycle: 100}

	err = engine.Execute(dataContext, kb)
	if err != nil {
		fmt.Println("Error executing rules:", err)
		return
	}

a1.grl

rule CalMiddleResult "Check Limits and Requests both setting rule" salience 4 {
	when
		F.HasKey("A") == false && F.HasKey("B") == false
	then
		F.MiddleResult["A"] = F.MetricMap["usage"] / F.MetricMap["limits"];
		F.MiddleResult["B"] = F.MetricMap["usage"] / F.MetricMap["requests"];
}

  1. With a test for this and that
  2. Instead of seeng this
  3. I see that

Expected behavior
A clear and concise description of what you expected to happen.

Additional context
Add any other context about the problem here.

when I add Changed ,it is ok

rule CalMiddleResult "Check Limits and Requests both setting rule" salience 4 {
	when
		F.HasKey("A") == false && F.HasKey("B") == false
	then
		F.MiddleResult["A"] = F.MetricMap["usage"] / F.MetricMap["limits"];
		F.MiddleResult["B"] = F.MetricMap["usage"] / F.MetricMap["requests"];
		Changed("F");
}

this helps me , 谢谢