我的定时规则不会触发 Drools 6.1。0.Final
My timed rule wont fire Drools 6.1.0.Final
我有两条规则。这是 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。在我的测试中 class 我设置了一个 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);
我在这个单元测试中进行了测试,验证所有规则在事件通过时触发,并且它们都通过了定时重试事件。我尝试测试handle事件,重试如下
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 中的定时事件有很大的改变吗?我已经放入调试行来验证时间提前和之后事件是否仍然存在,但是定时事件不会触发。
确实发生了变化,因为 (IIRC) Drools 团队似乎不喜欢由此产生的效果 and/or 未完全定义的计时器语义 运行 而规则引擎 未 活跃。 (请注意,您可以在一个会话中重复调用 session.fire*()
。)
在移动到 6.x 时,决定在引擎未 运行 时暂停触发计时器控制规则的激活。
您可以(使用您的规则,但使用 String 作为事实):
kieSession.insert( "Some fact" );
kieSession.fireAllRules();
System.out.println("sleep");
Thread.sleep( 8000 );
System.out.println("wake-up");
kieSession.fireUntilHalt();
您会观察到进入睡眠间隙的 "retry" 的触发被延迟到唤醒之后(并且未能遵守计时器中定义的时间)。
但如果您立即调用 fireUntilHalt,一切都会正常进行。您可能必须添加另一种机制才能正常关机。
我有两条规则。这是 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。在我的测试中 class 我设置了一个 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);
我在这个单元测试中进行了测试,验证所有规则在事件通过时触发,并且它们都通过了定时重试事件。我尝试测试handle事件,重试如下
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 中的定时事件有很大的改变吗?我已经放入调试行来验证时间提前和之后事件是否仍然存在,但是定时事件不会触发。
确实发生了变化,因为 (IIRC) Drools 团队似乎不喜欢由此产生的效果 and/or 未完全定义的计时器语义 运行 而规则引擎 未 活跃。 (请注意,您可以在一个会话中重复调用 session.fire*()
。)
在移动到 6.x 时,决定在引擎未 运行 时暂停触发计时器控制规则的激活。
您可以(使用您的规则,但使用 String 作为事实):
kieSession.insert( "Some fact" );
kieSession.fireAllRules();
System.out.println("sleep");
Thread.sleep( 8000 );
System.out.println("wake-up");
kieSession.fireUntilHalt();
您会观察到进入睡眠间隙的 "retry" 的触发被延迟到唤醒之后(并且未能遵守计时器中定义的时间)。
但如果您立即调用 fireUntilHalt,一切都会正常进行。您可能必须添加另一种机制才能正常关机。