我已经设置了流口水以在STREAM模式下运行。规则的执行通过fireUntilHalt()在其自己的线程中进行。我做了这样的事情:
protected KieSession getKieSession() {
if (this.kieSession == null) {
this.kieSession = kieBase.newKieSession(kieSessionConfig, null);
this.setSessionGlobals(this.kieSession);
new Thread(new Runnable() {
@Override
public void run() {
kieSession.fireUntilHalt();
}
}).start();
}
return this.kieSession;
}
然后我插入来自Rabbitmq的消息,仅调用getKieSession()。insert(fact)(包装在execRules()函数中,请参见下面的测试)。
在运行我的应用程序时,我使用的是实时时钟。问题来自于测试,使用相同的方式初始化会话和触发规则,但使用伪时钟。我有以下规则:
rule "rule 5"
no-loop
when
$l: ImageDTOList()
$h: UpdateHeartBeat( list == $l )
not( UpdateHeartBeat( this != $h, list == $l, this after[0s, 60s] $h ) )
then
System.out.println("rule 5");
delete( $l );
DroolsUtils.injectImageDTOListEvent($l);
end
以及以下测试:
@Test
public void testListEmitted() throws ParseException, InterruptedException {
// Carga de datos del test
ImageDTO dto1 = converter
.fromInputStream(getClass().getClassLoader().getResourceAsStream("amqp/escenario1/image1.json"));
ImageDTO dto2 = converter
.fromInputStream(getClass().getClassLoader().getResourceAsStream("amqp/escenario1/image2.json"));
ImageDTO dto3 = converter
.fromInputStream(getClass().getClassLoader().getResourceAsStream("amqp/escenario1/image3.json"));
consumer.execRules(dto1);
clock.advanceTime(10, TimeUnit.SECONDS);
System.out.println(clock.getCurrentTime());
consumer.execRules(dto2);
clock.advanceTime(10, TimeUnit.SECONDS);
System.out.println(clock.getCurrentTime());
consumer.execRules(dto3);
clock.advanceTime(65, TimeUnit.SECONDS);
System.out.println(clock.getCurrentTime());
consumer.getKieSession().fireAllRules();
Thread.sleep(3000);
}
测试输出为:
10000
20000
85000
rule 1
rule 3
rule 3
如果我实时模拟测试并运行应用程序,则在一分钟后,该应用程序将执行“规则1”,“规则3”,“规则3”,和“规则5” 。
因此,使用伪时钟(测试)时,第五条规则不会触发,这是唯一使用“之后”或任何其他时间运算符的规则。甚至在测试结束时,在睡眠调用之前添加手动“ fireAllRules()”也不会触发。
用伪时钟触发它的方式是什么?