我有两个规则。这与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中的定时事件有很大的改变吗?我已调入调试行来验证事件在时间提前之前和之后仍然存在,但定时事件不会触发。
答案 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,一切都会好起来的。您可能必须为正常关闭添加另一种机制。