我的时间规则不会解雇Drools 6.1.0.Final

时间:2015-02-23 21:41:48

标签: drools

我有两个规则。这与Drools 6.1.0.Final

有关
rule "HandleSomeEvent"
salience 5
no-loop
when
    $eventA  : SomeEvent()
then
    MyClass.handleSomeEvent($eventA); 
end


rule "HandleSomeEventRetry"
    timer(int: 15m 15m)  
    no-loop
    when
        $eventA  : SomeEvent()
    then
        MyClass.handleSomeEvent($eventA);
end

这些规则的测试在Drools 5.1.1中没有问题,但我试图重构到6.1.0.Final。在我的测试课中,我设置了一个KieSession

    KieServices ks = KieServices.Factory.get();
    KieContainer kContainer = ks.getKieClasspathContainer();

    KieBaseConfiguration kBaseConfig = ks.newKieBaseConfiguration();
    kBaseConfig.setOption(EqualityBehaviorOption.EQUALITY);
    KieBase kBase = kContainer.newKieBase(kBaseConfig);

    KieSessionConfiguration kSessionConfig =   ks.newKieSessionConfiguration();
    kSessionConfig.setOption(ClockTypeOption.get("pseudo"));

    ksession = kBase.newKieSession(kSessionConfig, null);

    SessionPseudoClock clock = ksession.getSessionClock();
    ksession.setGlobal("MyClass", MyClass);

我在这个单元测试中进行了测试,验证了所有规则在事件发生时触发,并且它们都通过了该定时重试事件。我尝试测试句柄事件和重试如下

    SomeEvent e...
    AgendaEventListener ael = mock(AgendaEventListener.class);
    ksession.addEventListener(ael);
    ksession.insert(e);
    ksession.fireAllRules();

    clock.advanceTime(15, TimeUnit.MINUTES);

    ArgumentCaptor<AfterMatchFiredEvent> amfe = ArgumentCaptor.forClass(AfterMatchFiredEvent.class);
    verify(ael, times(2)).afterMatchFired(amfe.capture());

使用5.1.1进行测试时,我还可以从ArgumentCaptor中获取事件并验证触发的各个规则的名称。第一个是初始,第二个是定时重试。但是使用6.1.0.Final只会触发一个Match。我找不到任何文档来支持这一点,但6.1中的定时事件有很大的改变吗?我已调入调试行来验证事件在时间提前之前和之后仍然存在,但定时事件不会触发。

1 个答案:

答案 0 :(得分:0)

确实存在变化,因为(IIRC)Drools团队似乎不喜欢在规则引擎活动时运行的计时器产生的效果和/或未完全定义的语义。 (请注意,您可以在会话中反复调用session.fire*()。)

在转移到6.x时,决定暂停在发动机未运行时触发定时器控制规则的激活。

您可以(使用您的规则但使用字符串表示事实):

        kieSession.insert( "Some fact" );
        kieSession.fireAllRules();
        System.out.println("sleep");
        Thread.sleep( 8000 );
        System.out.println("wake-up");
        kieSession.fireUntilHalt();

你会发现,进入睡眠间隙的“重试”的触发会延迟到唤醒之后(并且无法遵守计时器中定义的时间)。

但如果你马上打电话给fireUntilHalt,一切都会好起来的。您可能必须为正常关闭添加另一种机制。