甩锅声明:本人英语一般,翻译只是为了做个笔记,所以有翻译错误的地方,错就错了,如果你想给我纠正,就给我留言,我会改过来,如果懒得理我,就直接划过即可。  

Drools用户手册翻译——第四章 Drools规则引擎(八)drools中的事实传播模式和议程评估过滤器-LMLPHP

 

drools中的事实传播模式

drools支持下面的事实传播模式,这些模式决定了drools如何通过引擎网络推进插入的事实,用来为执行规则做准备:

  • Lazy(延迟模式):(默认) 事实在规则执行时在批量集合中传播,而不是作为插入的单条事实去实时传播。因此,事实最终的传播顺序,和事实插入的顺序是不一样的。

  • Immediate(立即模式):事实会立即传播,而且事实传播的顺序就是事实插入时的顺序。

  • Eager(急切模式):事实被延迟传播(在批处理集合中),但是是在规则执行之前。drools的这种传播行为是为了那些设置了no-loop或者lock-on-active属性的规则。

默认的,为了全面提高规则评估,drools的Phreak规则算法使用懒加载事实传播。但是,在少数情况下,懒加载能改变某些规则执行的预期结果,这些规则执行就需要立即传播或者eager传播。

例如,下面的规则用?前缀的指定查询,用来仅拉取或被动方式调用查询:

使用被动查询规则的示例

query Q (Integer i)
    String( this == i.toString() )
end

rule "Rule"
  when
    $i : Integer()
    ?Q( $i; )
  then
    System.out.println( $i );
end

对于这个例子,在插入整数之前,只有当插入满足查询的字符串时,规则才会被执行,例如下面的示例命令:

触发规则执行的示例命令

KieSession ksession = ...
ksession.insert("1");
ksession.insert(1);
ksession.fireAllRules();

但是,由于在Phreak中默认的传播行为是懒加载,drools没有检测到两个事实的插入顺序,所以,不论字符串和整数的插入顺序如何,这个规则都会执行。对于这个例子,为了预期的规则评估,需要立即传播。

在这个情况下,为了完成预期的规则评估,更改drools的传播模式,你可以在你的规则上添加@Propagation(<type>)注解,并且设置<type>为LAZY,IMMEDIATE或者EAGER。

这相同的示例规则下,立即传播注解能够像预期的那样执行规则评估:

使用被动查询和指定传播模式的规则示例

query Q (Integer i)
    String( this == i.toString() )
end

rule "Rule" @Propagation(IMMEDIATE)
  when
    $i : Integer()
    ?Q( $i; )
  then
    System.out.println( $i );
end

议程评估过滤器

Drools用户手册翻译——第四章 Drools规则引擎(八)drools中的事实传播模式和议程评估过滤器-LMLPHP

图示5.议程过滤器

drools在过滤器接口中支持AgendaFilter对象,在议程评估阶段,这个对象可以允许或者拒绝指定规则的评估。你可以指定一个议程过滤器作为fireAllRules方法调用的一部分。

下面的实例代码 只允许带有字符串"Test"结尾的规则被评估和执行。所有其他的规则都会被过滤器过滤掉。

议程过滤器的定义示例

ksession.fireAllRules( new RuleNameEndsWithAgendaFilter( "Test" ) );

 

07-29 14:52