【问题标题】:Order of objects retrieved from working memory in Drools在 Drools 中从工作内存中检索到的对象的顺序
【发布时间】:2017-07-26 13:21:33
【问题描述】:

我们一直在编写一个规则,该规则可以更改在同一天重复的已计费项目的状态,并且每天只应计费一次。所有项目的状态都是从 2 或 3 开始。

如果在状态 2 或 3 的项目上检测到重复代码,则该项目将获得状态 4 并更新工作内存中的项目。

当实现单元测试时,我们可以看到结果是正确的,但是一旦我们从工作内存中检索对象,似乎项目的顺序已经变成了几乎随机的。 这是正常的吗?为什么会这样? (显然,如果有异常,可以通过重新排序列表来纠正)。

对象以这种方式插入:

Iterator<Object> it = objects.iterator();
while (it.hasNext()) {
    sessionStatefull.insert(it.next());
}

它的日志是通过在KieSession中添加一个logger来实现的:

public static KieSession getStatefulKnowledgeSessionWithCallback(KieContainer kieContainer, String sessionName) {
   KieSession kieSession = null;
    try {
        kieSession = getStatefulKnowledgeSession(kieContainer, sessionName);
        kieSession.addEventListener(new RuleRuntimeEventListener() {
            OutputDisplay outputDisplay = new OutputDisplay();

            @Override
            public void objectInserted(ObjectInsertedEvent objectInsertedEvent) {
                outputDisplay.showText("getStatefulKnowledgeSessionWithCallback.INSERT", objectInsertedEvent.getObject().toString());               
            }

输入总是一样的:

Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169800, units=1.0, code=1   ]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169801, units=1.0, code=1   ]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169802, units=1.0, code=2   ]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169803, units=1.0, code=2   ]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169804, units=1.0, code=6358]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169805, units=1.0, code=6007]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169806, units=1.0, code=6007]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169807, units=1.0, code=6385]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169808, units=1.0, code=6005]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169809, units=1.0, code=6225]

这样得到输出:

    List<Object> list = new ArrayList<Object>((Collection<Object>) sessionStatefull.getObjects());

它的日志是通过迭代器获得的:

    Iterator<Object> it2 = list.iterator();
    while (it2.hasNext()) {
        Object object = it2.next();
        outputDisplay.showText("Result: ", object.toString());
    }

打印的输出似乎总是有一个随机的顺序:

示例 1:

Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169809, units=1.0, code=6225]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=4, id=150107315169801, units=1.0, code=1   ]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169800, units=1.0, code=1   ]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=4, id=150107315169803, units=1.0, code=2   ]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169802, units=1.0, code=2   ]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169807, units=1.0, code=6385]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169805, units=1.0, code=6007]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169804, units=1.0, code=6358]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=4, id=150107315169806, units=1.0, code=6007]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169808, units=1.0, code=6005]

示例 2:

Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169804, units=1.0, code=6358]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=4, id=150107315169803, units=1.0, code=2   ]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=4, id=150107315169806, units=1.0, code=6007]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169805, units=1.0, code=6007]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=4, id=150107315169801, units=1.0, code=1   ]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169808, units=1.0, code=6005]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169807, units=1.0, code=6385]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169800, units=1.0, code=1   ]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169809, units=1.0, code=6225]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169802, units=1.0, code=2   ]

记录器类是这样定义的:

public class OutputDisplay {

    public void showText(String source, String text) {
        try {
            long time = System.currentTimeMillis();
            Date date = new Date(time);
            writeLog(time+" "+date.toString()+" A message from "+source+": "+text);

        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }

writeLog 打开一个文件并添加该行。我们还没有关注一些更复杂的日志记录(即 logback...)。

【问题讨论】:

  • 你是如何从工作记忆中提取这些对象的?
  • 您好,感谢您的回复。我编辑了问题,为您提供您要求的信息。

标签: drools rule


【解决方案1】:

Drools 不会在内部保持插入对象的顺序。您正在使用的getObjects() 方法通过返回Collection 而不是List 来说明这一点。

记录器按顺序显示对象,因为一旦将新对象插入到工作内存中就会调用它。

如果你想给你的对象一些逻辑顺序,我建议你在从工作记忆中检索它们之后对它们进行排序。

希望对你有帮助,

【讨论】:

  • 您的回答绝对有帮助。很高兴知道 Drools 内部没有维护订单,如果需要,应该在流程中实现某种排序。
猜你喜欢
  • 1970-01-01
  • 2015-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-28
  • 1970-01-01
  • 2015-07-03
相关资源
最近更新 更多