首页 文章

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

提问于
浏览
0

我有两个规则 . 这与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

    确实存在变化,因为(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打电话,一切都很好 . 您可能必须为正常关闭添加另一种机制 .

相关问题