在 Drools 6 中执行成功规则后退出

Posted

技术标签:

【中文标题】在 Drools 6 中执行成功规则后退出【英文标题】:Exiting after executing a successful rule in Drools 6 【发布时间】:2015-06-11 09:21:24 【问题描述】:

我有一个对象如下:

class License
    private field1;
    private field2;
    private boolean active;
    private String activeMessage;
    private boolean processed = false;

    //Getter and setter methods

我要做的是,根据 field1 和 field2 的值,我需要设置 isActive 标志和相应的消息。但是,如果 field1 或 field2 的规则被触发,我需要停止规则处理。也就是说,我只需要执行一条成功的规则。

我在一篇文章中读到,执行 ksession.fireAllRules(1) 将解决此问题。但是 fireAllRules() 方法在 Drools 6 中不可用。我也尝试过返回;在每条规则的末尾声明。这对我也没有帮助。

最后,我最终向我的对象添加了一个名为已处理的附加字段。因此,每当我执行任何规则时,我都会将已处理标志设置为 true。如果标志已经设置,那么我不执行任何规则。这是我的规则文件:

rule "Check field1"
    when
        $obj : License(getField1() == "abc" && isProcessed() == false)
    then
        System.out.println("isProcessed >>>>>> "+$obj.isProcessed());
        $obj.setActive(true);
        $order.setActiveMessage("...");
        $order.setProcessed(true);
end


rule "Check field2"
    when
        $obj : License(getField2() == "def" && isProcessed() == false)
    then
        System.out.println("isProcessed >>>>>> "+$obj.isProcessed());
        $obj.setActive(true);
        $order.setActiveMessage("...");
        $order.setProcessed(true);
end

但是,我发现即使现在我的两条规则都被解雇了。当我尝试打印 isProcessed() 的值时,它显示为 true,即使我仅在 isProcessed() 为 false 时才输入规则。

这就是我对 drools 引擎的称呼:

kieService = KieServices.Factory.get();
kContainer = kieService.getKieClasspathContainer();
kSession = kContainer.newStatelessKieSession();
kSession.execute(licenseObj);

不只是2条规则,我有很多规则,所以不能通过改变drl文件中规则的顺序来控制规则的执行。这里发生了什么?我怎么解决这个问题?我对 Drools 有点陌生,所以我可能在这里遗漏了一些东西。

谢谢。

【问题讨论】:

【参考方案1】:

您的问题包含许多错误。

fireAllRules 在 Drools 6 中消失绝对不是真的。您可能已经查看了 javadoc 索引,在接口 StatefulRuleSession 的包 org.kie.api.runtime.rule 中找到了此方法的四个(4!)重载版本.

通过组合触发约束,您可以轻松避免仅触发两条规则之一的问题:

rule "Check field1 and field2"
when
    $lic: License(getField1() == "abc" || getField2() == "def" )
    //...
then
    $lic.setXxx(...);
end

您抱怨尽管设置了processed 标志,但您的两条规则都会触发。在这里,您遗漏了一个基本要点(Drools 参考手册中对此进行了介绍),即每当您更改事实数据时都必须通知引擎。您应该在规则的右侧使用modify

但即使这样也不够好。每当由于某些属性进行更新时,都应添加约束以避免一遍又一遍地运行更新。你可能写过:

rule "Check field1 and field2"
when
    $lic: License(getField1() == "abc" || getField2() == "def",
                  ! active )
    //...
then
    modify( $lic ) setActive( true ) 
end

您甚至可以用两个不同的规则编写此代码,每个字段一个,并且这些规则中只有一个会触发...

【讨论】:

谢谢,修改($lic) 成功了。我的印象是事实数据是按顺序传递给规则的,因此更新规则内的数据也会反映到其他规则中。我无法合并这些规则,因为我在每个规则中都做了很多其他操作。我发布的代码只是一个示例。

以上是关于在 Drools 6 中执行成功规则后退出的主要内容,如果未能解决你的问题,请参考以下文章

jboss规则引擎KIE Drools 6.3.0 Final 教程

在 Drools 6 中以编程方式创建新的 drools 规则的新接受方式是啥?

成功执行后,我的 nodejs 脚本不会自行退出

[简易的网站登录注册,注销退出操作]

在 Node.js 中如何停止脚本执行,成功向控制台写入错误消息,然后退出脚本?

跟我一起写Makefile