gengine icon indicating copy to clipboard operation
gengine copied to clipboard

concurrent map writes

Open hubao opened this issue 4 years ago • 9 comments

debug模式下

context/data_context.go:371 ==> Vars[variable] = newValue. 限制同时10个50个goroutinue并发请求,均出现过concurrent map writes,map读写问题。

请求场景: func API(ctx context.Context, req *Request) error { data := make(map[string]interface{}) data["req"] = req data["stg_name"] = &stgName

err, _ = engine.EngPool.ExecuteSelectedRules(data, stgRule)
    // do sth ...

}

release并未发现。

hubao avatar May 24 '21 13:05 hubao

用户自己注入的api的,需要用户自己保证线程安全。

rencalo770 avatar May 24 '21 13:05 rencalo770

image 只注入了一个api,这个有问题吗?

hubao avatar May 26 '21 09:05 hubao

这个是个纯函数,看起来没问题

rencalo770 avatar May 26 '21 14:05 rencalo770

仔细验证了一下,出现问题的规则如下: rule "stg_rule_0421" "s1" begin ids=split("1,3,4,5,6,9999", ",") if contains(req.ID, ids) { stg_name = "stg0421" } end panic的原因在map的并发写入,这个case是由于在map中并发写入ids这个key。 ==> data_context.go:37

hubao avatar May 28 '21 07:05 hubao

嗯,用户注入普通的map,自己要保证不能并发写。就像在golang中,用户不能用使用多协程去并发读写非线程安全的map表现是一致的。

rencalo770 avatar May 28 '21 07:05 rencalo770

😅 我没写清楚,我的意思是如果走到如图的分支,可能会出问题。 image

hubao avatar May 28 '21 10:05 hubao

最新版本已经到v1.5.5了,可以用最新版本看看。 另外,麻烦你您能把完整的规则和执行模式贴出来让我看看吗? 你上面截图指的这一行,它的作用是设置你在规则中自定义的变量的值,如“a = X”,a是你在规则中定义的变量,X可能是函数,也可能是取map值的操作等。其中varible就是字面“a”, newValue就是“X”表达式计算出来之后的值,Vars是个内置map空间,并不是用户自定义的map, 也即“并不是在X计算过程中的操作”,所以会受到锁的保护。

如果你有兴趣深入了解,并快速交流,欢迎加入QQ交流群1132683357,再加入微信群。

rencalo770 avatar May 29 '21 02:05 rencalo770

请问gengine的规则里面,不支持for循环吗?只能通过下标一个个单独去访问吗?多谢

fxdgg avatar Jul 21 '21 09:07 fxdgg

请问gengine的规则里面,不支持for循环吗?只能通过下标一个个单独去访问吗?多谢

最新版已经支持了

rencalo770 avatar Aug 22 '21 04:08 rencalo770