[jboss-jira] [JBoss JIRA] (DROOLS-2240) Timer rules with pseudo clock don't fire
Mario Fusco (JIRA)
issues at jboss.org
Fri Jan 12 11:50:00 EST 2018
[ https://issues.jboss.org/browse/DROOLS-2240?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Mario Fusco resolved DROOLS-2240.
---------------------------------
Resolution: Explained
You have a rule that is fires every second, have a pseudo-clock that makes a jump of 10 seconds in one shoot and expect the rule to fire 10 times. This is not how the psuedo-clock is supposed to work. Conversely time conditions are evaluated once at each discrete jump so what happens when you do 10 seconds jump is that the timestamp for the next expected rule firing is compared with the current time and if it's lower the rule fires once and that's all. When instead of do 10 subsequent jumps the condition is evaluated 10 times and then also the rule fires 10 times as per your expectations.
> Timer rules with pseudo clock don't fire
> ----------------------------------------
>
> Key: DROOLS-2240
> URL: https://issues.jboss.org/browse/DROOLS-2240
> Project: Drools
> Issue Type: Bug
> Affects Versions: 7.5.0.Final
> Reporter: Christian Bauer
> Assignee: Mario Fusco
>
> We are trying to test rules with timer option and the pseudo clock.
> The problem can probably also be seen by enabling (note the @Ignore) this test: https://github.com/kiegroup/drools/blob/master/drools-compiler/src/test/java/org/drools/compiler/integrationtests/CepFireUntilHaltTimerTest.java
> Based on this class, this is a minimal test that shows the problem:
> {code}
> import org.drools.core.time.SessionPseudoClock;
> import org.junit.Test;
> import org.kie.api.KieServices;
> import org.kie.api.builder.KieFileSystem;
> import org.kie.api.builder.model.KieBaseModel;
> import org.kie.api.builder.model.KieModuleModel;
> import org.kie.api.runtime.KieSession;
> import org.kie.api.runtime.conf.ClockTypeOption;
> import java.util.concurrent.ExecutorService;
> import java.util.concurrent.Executors;
> import java.util.concurrent.Future;
> import java.util.concurrent.TimeUnit;
> import static org.junit.Assert.assertEquals;
> /**
> * Based on:
> * https://github.com/kiegroup/drools/blob/master/drools-compiler/src/test/java/org/drools/compiler/integrationtests/CepFireUntilHaltTimerTest.java
> */
> public class PseudoClockTimerTest {
> private KieSession ksession;
> private SessionPseudoClock clock;
> public void init(String clockType) {
> String drl = "package test.rules\n" +
> "\n" +
> "rule \"Do something triggered by timer\"\n" +
> "timer (int: 1s 1s)\n" +
> "then\n" +
> " System.out.println(\"### DO SOMETHING \" + drools.getWorkingMemory().getSessionClock().getCurrentTime());\n" +
> " insert(\"### TIME IS \" + drools.getWorkingMemory().getSessionClock().getCurrentTime());\n" +
> "end\n";
> KieServices ks = KieServices.Factory.get();
> KieModuleModel module = ks.newKieModuleModel();
> KieBaseModel defaultBase = module.newKieBaseModel("defaultKBase")
> .setDefault(true)
> .addPackage("*");
> defaultBase.newKieSessionModel("defaultKSession")
> .setDefault(true)
> .setClockType(ClockTypeOption.get(clockType));
> KieFileSystem kfs = ks.newKieFileSystem()
> .write("src/main/resources/r1.drl", drl);
> kfs.writeKModuleXML(module.toXML());
> ks.newKieBuilder(kfs).buildAll();
> ksession = ks.newKieContainer(ks.getRepository().getDefaultReleaseId())
> .newKieSession();
> if (clockType.equals("pseudo"))
> clock = ksession.getSessionClock();
> }
> public void cleanup() {
> ksession.dispose();
> }
> @Test
> public void testTimerExecution() throws Exception {
> init("realtime");
> performRealtimeClockTest();
> cleanup();
> init("pseudo");
> performPseudoClockTest();
> cleanup();
> }
> private void performRealtimeClockTest() throws Exception {
> ExecutorService thread = Executors.newSingleThreadExecutor();
> final Future fireUntilHaltResult = thread.submit(() -> ksession.fireUntilHalt());
> try {
> Thread.sleep(10500);
> assertEquals(10, ksession.getFactCount());
> } finally {
> ksession.halt();
> fireUntilHaltResult.get(60000, TimeUnit.SECONDS);
> thread.shutdown();
> }
> }
> private void performPseudoClockTest() throws Exception {
> ExecutorService thread = Executors.newSingleThreadExecutor();
> final Future fireUntilHaltResult = thread.submit(() -> ksession.fireUntilHalt());
> try {
> Thread.sleep(500);
> // NOT WORKING:
> // clock.advanceTime(10, TimeUnit.SECONDS);
> // Thread.sleep(50);
> // WORKAROUND:
> for (int i = 0; i < 10; i++) {
> clock.advanceTime(1, TimeUnit.SECONDS);
> Thread.sleep(50);
> }
> assertEquals(10, ksession.getFactCount());
> } finally {
> ksession.halt();
> fireUntilHaltResult.get(60000, TimeUnit.SECONDS);
> thread.shutdown();
> }
> }
> }
> {code}
> See the NOT WORKING and WORKAROUND markers. There doesn't seem to be any other test in the codebase with timer rules and the pseudo clock, so our conclusion is that this combination is not working at all.
--
This message was sent by Atlassian JIRA
(v7.5.0#75005)
More information about the jboss-jira
mailing list