代码之家  ›  专栏  ›  技术社区  ›  Wes Taylor

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

  •  0
  • Wes Taylor  · 技术社区  · 11 年前

    我有两条规则。这是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());
    

    使用5.1.1测试时,我还可以从ArgumentCaptor中获取事件,并验证激发的单个规则的名称。第一次是初始重试,第二次是定时重试。然而,在6.1.0决赛中,甚至只有一场比赛被激发。我找不到任何支持这一点的文档,但6.1中的计时事件是否发生了重大变化?我已经插入了调试行,以验证事件在时间提前之前和之后仍然存在,但定时事件不会触发。

    1 回复  |  直到 11 年前
        1
  •  0
  •   laune    11 年前

    确实有一个变化,因为(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();
    

    您将观察到,进入睡眠间隙的“重试”的发射延迟到唤醒后(并且未能遵守计时器中定义的时间)。

    但如果你马上叫火,一切都很好。您可能需要添加另一种机制来实现优雅的关机。