RulesEngine
RulesEngine copied to clipboard
AddOrUpdateWorkflow has a problem with delayed effect of rules
I have a program that is used in a production environment. His working principle is to first get the item information to do rule matching, if the match fails, automatically generate a new rule, and then update the rule by AddOrUpdateWorkflow(workflow). Now the problem is that Task 4 generates AutoRule-6, Task 6 has the same model name information as Task 4, but Task 6 fails to match and creates AutoRule-7 with the same expression as AutoRule-6, but the other tasks after it can match AutoRule-6 correctly.
Task4 log info
2022-06-16 15:28:51.635 +08:00 [INF] task4-request info:{"actionResult":1,"goodsBaseInfo":{"brand":"Apple","model":"A1984","modelName":"iPhone XR","capacity":"64GB","color":"Coral","deviceStatus":"Power up","service":"Pass","mdm":"Pass","carrier":"Pass","esn":"unknown","bio":"Yes","display":"Yes","camera":"Yes","cdt":"K3","modelNumber":"MRYW2LL/A","gpeMc":null,"fpiMc":null,"dpeMc":null,"abbreviation":null},"readText":null}
2022-06-16 15:28:51.635 +08:00 [INF] 规则引擎匹配失败 开始自动生成该通道号:6 对应匹配规则
2022-06-16 15:28:51.635 +08:00 [INF] 自动生成通道号:6 对应的匹配规则:{"RuleName":"AutoRule-6","Properties":null,"Operator":null,"ErrorMessage":"This Rule is not match!!!","Enabled":true,"ErrorType":0,"RuleExpressionType":0,"WorkflowRulesToInject":null,"WorkflowsToInject":null,"Rules":null,"LocalParams":null,"Expression":"input1.ModelName== \u0022iPhone XR\u0022 ","Actions":null,"SuccessEvent":"6"}
take6 log info
2022-06-16 15:28:58.433 +08:00 [INF] task6-request info:{"actionResult":1,"goodsBaseInfo":{"brand":"Apple","model":"A1984","modelName":"iPhone XR","capacity":"64GB","color":"Red","deviceStatus":"Power up","service":"Pass","mdm":"Pass","carrier":"Pass","esn":"unknown","bio":"Yes","display":"Yes","camera":"Yes","cdt":"K3","modelNumber":"MRYU2LL/A","gpeMc":null,"fpiMc":null,"dpeMc":null,"abbreviation":null},"readText":null}
2022-06-16 15:28:58.433 +08:00 [INF] 规则引擎匹配失败 开始自动生成该通道号:7 对应匹配规则
2022-06-16 15:28:58.433 +08:00 [INF] 自动生成通道号:7 对应的匹配规则:{"RuleName":"AutoRule-7","Properties":null,"Operator":null,"ErrorMessage":"This Rule is not match!!!","Enabled":true,"ErrorType":0,"RuleExpressionType":0,"WorkflowRulesToInject":null,"WorkflowsToInject":null,"Rules":null,"LocalParams":null,"Expression":"input1.ModelName== \u0022iPhone XR\u0022 ","Actions":null,"SuccessEvent":"7"}
method BulidRule
private void BulidRule(GoodsInfo response, List<FieldItem> fields, int channelNo)
{
bool IsFieId = true;
if (response is null)
{
Serilog.Log.Information("没有可以供生成规则的数据源 提前返回");
return;
}
//生成规则
if (rules is null)
{
rules = new List<Rule>();
}
if (fields.Count == 0)
{
IsFieId = false;
}
var rule = new Rule
{
RuleName = "AutoRule-" + channelNo.ToString(),
RuleExpressionType = RuleExpressionType.LambdaExpression,
SuccessEvent = channelNo.ToString(),
ErrorMessage = "This Rule is not match!!!"
};
string expression = string.Empty;
if (IsFieId)
{
List<PropertyInfo> properties = new List<PropertyInfo>();
foreach (var item in fields)
{
PropertyInfo propertyInfo = response.GetType().GetProperties().SingleOrDefault(x => x.Name == item.Name);
if (propertyInfo is null)
{
break;
}
properties.Add(propertyInfo);
}
if (properties.Count <= 0)
{
Serilog.Log.Warning("异常情况 规则生成 属性字段不匹配 无法生成规则 失败!!!");
return;
}
for (int i = 0; i < properties.Count; i++)
{
string value = properties[i].GetValue(response, null)?.ToString();
if (value is null)
{
value = string.Empty;
}
expression += string.Format("input1.{0}== \"{1}\" ", properties[i].Name, value);
if (i != properties.Count - 1)
{
expression += " And ";
}
}
}
if (IsEableGrade)
{
if (GradeGroup.ContainsKey(response.Condition))
{
GradeGroup.TryGetValue(response.Condition, out int value);
//等级分组 规则表达式用||联起来
if (Grades.TryGetValue(value, out List<CellPhoneGrade> cdtList))
{
if (!string.IsNullOrEmpty(expression))
{
expression += " And ";
}
foreach (var item in cdtList)
{
expression += string.Format("input1.Condition == \"{0}\" ||", item.Condition);
}
expression = expression.TrimEnd("||".ToCharArray());
}
else
{
Serilog.Log.Warning("没有从Grades找到对应的等级信息");
}
}
else
{
if (!string.IsNullOrEmpty(expression))
{
expression += " And ";
}
expression += string.Format("input1.{0}== \"{1}\" ", "Condition", response.Condition);
}
}
rule.Expression = expression;
Serilog.Log.Information("自动生成通道号:{0} 对应的匹配规则:{1}", channelNo, JsonSerializer.Serialize(rule));
rules.Add(rule);
var workflow = new Workflow()
{
WorkflowName = "Automatic Sorting",
Rules = rules
};
if (engine is null)
{
engine = new RulesEngine.RulesEngine();
}
engine.AddOrUpdateWorkflow(workflow);
}
method RunEnginseAsync
private async Task<int> RunEnginseAsync(GoodsInfo response)
{
int result = 0;
try
{
List<RuleResultTree> resultList = await engine.ExecuteAllRulesAsync("Automatic Sorting", response);
resultList.OnSuccess((eventName) =>
{
bool IsSuccess = int.TryParse(eventName, out result);
result = IsSuccess ? result : 0;
if (!IsSuccess)
{
Serilog.Log.Information("转换失败 将采用失败通道号0 源数据:{0}", eventName);
}
Serilog.Log.Information("{0} 匹配到通道号:{1}", "规则引擎匹配成功", result);
});
resultList.OnFail(() =>
{
result = GetEmptyChannel();
if (result != 0)
{
Serilog.Log.Information("{0} 开始自动生成该通道号:{1} 对应匹配规则", "规则引擎匹配失败", result);
BulidRule(response, FieldItemList, result);
}
});
}
catch (Exception ex)
{
Serilog.Log.Information("匹配规则异常{0}", ex.ToString());
result = 0;
}
return result;
}
So, is it possible that AddOrUpdateWorkflow has a problem with delayed effect of rules?