在drools中,如何通过API访问无状态会话的事实/工作内存?

时间:2015-12-04 15:19:06

标签: drools

我可以看到,对于有状态的会话,例如。

StatefulKnowledgeSessionImpl.getFactHandles() 

如何访问无状态会话的事实句柄?

更多背景: 这是对此的后续问题:In drools can I access the working memory (or arbitrary facts) from within an AgendaFilter? 我试图找到一种方法来从AgendaFilter中访问任意事实。 接受的答案(https://stackoverflow.com/a/34067851/932201)建议将kieSession添加到过滤器,但我没有提到我正在使用无状态会话。

谢谢!

1 个答案:

答案 0 :(得分:0)

我认为你的问题是不连贯的,因为我认为不可能将AgendaFilter传递给无状态会话的执行方法;没有可用于.execute()的API方法,您可以将AgendaFilter作为参数传递。 编辑:,如评论中指出的那样AgendaFilter 1}}实际上可以在FireAllRulesCommand内传递。

此外,问题序言有点令人困惑,无状态会话在您传递事实和上下文启动规则评估时创建和处理,没有可能访问事实处理来自API,因为会话已在您调用.execute(Object...)时处理,因此不再处理事实。

反正 -

通过查看您之前提出的问题的答案,以及IFF您想要跟进建议的

  

稍微复杂一点的方法是

用户@laune建议,通过绑定AgendaEventListener可能类似于下面的内容:

kieBase.newStatelessKieSession().addEventListener(new AgendaEventListener() {
    @Override
    public void afterMatchFired(AfterMatchFiredEvent event) {
        final String uid = (String) event.getMatch().getRule().getMetaData().get("uid"); // @uid("1234")
        @SuppressWarnings("unchecked") // is unchecked yes, but anyway okay because of ObjecFilter.
        Collection<? extends RuleConfig> facts = (Collection<? extends RuleConfig>) event.getKieRuntime().getObjects(object -> {
                if (object instanceof RuleConfig) {
                    return ((RuleConfig) object).getUid().equals(uid);
                }
                return false;
            });
        facts.forEach(o -> { o.decrementCounter();});

        // trickiest part, because need to signal updated Facts via the facthandles;
        for ( RuleConfig rc : facts ) {
            FactHandle factHandle = event.getKieRuntime().getFactHandle(rc);
            event.getKieRuntime().update(factHandle, rc);
        }
    }

,虽然你仍然需要在每个规则LHS中根据@laune示例在该答案的最后部分中提供一个条件:

rule "abc"
@uid("1234")
when
  $ruleConfig : RuleConfig(uid="1234", counter > 0)
  // ...