我的定时规则不会触发Drools 6.1.0.Final

我的定时规则不会触发Drools 6.1.0.Final,drools,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 : So

我有两条规则。这是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。在我的测试课上,我设置了一个会话

    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());
SomeEvent e。。。
AgendaEventListener ael=mock(AgendaEventListener.class);
K会话添加列表器(ael);
K段.插入(e);
ksession.fireAllRules();
时钟提前时间(15,时间单位为分钟);
ArgumentCaptor amfe=ArgumentCaptor.forClass(在MatchFireDevent.class之后);
验证(ael,次数(2)).afterMatchFired(amfe.capture());

在使用5.1.1进行测试时,我还可以从ArgumentCaptor获取事件,并验证触发的各个规则的名称。第一个是初始值,第二个是定时重试。然而,在6.1.0.1决赛中,只有一场比赛被触发。我找不到任何文档来支持这一点,但6.1中的定时事件是否有过重大更改?我已经加入了调试行,以验证事件在时间推进之前和之后仍然存在,但计时事件不会触发。

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

在移动到6.x时,决定在引擎未运行时暂停启动定时器控制规则

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

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


但如果你马上打电话给fireUntilHalt,一切都会很好。您可能需要添加另一种机制才能正常关机。

谢谢。只需在clock.advanceTime之后添加另一个ksession.fireAllRules(),即可触发重试规则。
        kieSession.insert( "Some fact" );
        kieSession.fireAllRules();
        System.out.println("sleep");
        Thread.sleep( 8000 );
        System.out.println("wake-up");
        kieSession.fireUntilHalt();