当前位置: 首页 > 知识库问答 >
问题:

我的定时规则不会触发Drools 6.1.0。最终的

宓跃
2023-03-14

我有两个规则。这是Drools 6.1.0。最终

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。最终。在我的测试类中,我设置了一个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。决赛只进行了一场比赛。我找不到任何文档来支持这一点,但6.1中的定时事件是否有过重大更改?我已经插入了调试行,以验证事件在时间提前之前和之后仍然存在,但定时事件不会触发。

共有1个答案

卫学真
2023-03-14

确实发生了变化,因为(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打电话,一切都会很好。您可能需要添加另一种机制以实现正常关机。

 类似资料:
  • 这两个在Drools中有什么区别??意味着我们可以根据 从加载的规则库和触发规则创建WorkingMemory,如下所示: vs公司 使用会话(有状态的。无状态)触发规则,如图所示

  • 我刚开始流口水,遇到了一个问题。 我简化了规则以显示问题: 基本上,我想计算特定路段上发生的事件(路段是道路的一部分)。当同一链接上发生3个事件时,我希望触发规则。 上面的规则几乎起作用了,但是当它发射时,它发射了3次,每个事件发射一次。我只希望它发射一次。 我错过了什么? 非常感谢。

  • 我有一个简单的JAVA bean,有两个int字段:'a'和'b'。 更新 非常感谢你的回答。 也许我应该详细描述一下我的问题。我有一套1500条规则。每条规则: null Java代码: 解决方案2的DRL文件:我向每个规则添加了相同的激活组:

  • 我对口水很陌生,从基础开始。这是一个设置; > 有一些规则文件 不同文件中的规则属于不同的议程组 所有规则都基于同一事实 在我的单元测试中,我获得了一个特定的“议程组”,设置焦点(

  • 我有一个多用途的传感器,每个传感器发送计步器数据。我有一个基于macAddress的规则文件,触发规则: My User只有一个字段,Steps事件有以下字段: 现在,当我为每个macAddress插入一个事件时,如果在过去一小时内使用该macAddress的用户的步骤数少于50,则规则将触发。因此,如果满足此条件,则该规则将为每个macAddress触发。但我希望规则只能为插入的步骤事件的mac

  • null 我在上面试图指出的是,只有在执行第一个规则时,第二个规则才会执行。但是,正如我所理解的,规则的“如果”部分是在“然后”部分之前执行的,因此,第二条规则失败了。