]
Mario Fusco commented on DROOLS-1130:
-------------------------------------
Reproduced with the following test case
{code}
@Test(timeout=10000)
public void testCascadingTimedRule() throws Exception {
String drl =
"package org.simple \n" +
"import " + AtomicInteger.class.getCanonicalName() +
"\n" +
"rule R1 \n" +
" timer (int:30s) " +
"when \n" +
" $i : AtomicInteger(get() == 1)" +
"then \n" +
" modify($i) { set(2) }; \n" +
"end \n" +
"rule R2 \n" +
"when \n" +
" $i : AtomicInteger(get() == 2)" +
"then \n" +
" modify($i) { set(3) }; \n" +
"end \n";
KieSessionConfiguration conf =
KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
conf.setOption( ClockTypeOption.get( "pseudo" ) );
conf.setOption( TimedRuleExectionOption.YES );
KieSession ksession = new KieHelper().addContent( drl, ResourceType.DRL )
.build()
.newKieSession( conf, null );
PseudoClockScheduler timeService = ( PseudoClockScheduler )
ksession.<SessionClock>getSessionClock();
timeService.advanceTime( new Date().getTime(), TimeUnit.MILLISECONDS );
AtomicInteger i = new AtomicInteger( 1 );
ksession.insert( i );
ksession.fireAllRules();
timeService.advanceTime( 35, TimeUnit.SECONDS );
assertEquals(3, i.get());
}
{code}
Using fireAllRules, Timed rules does not cascade rule execution after
modifying a fact, event when Session conf is set to TimedRuleExectionOption.YES
-----------------------------------------------------------------------------------------------------------------------------------------------------
Key: DROOLS-1130
URL:
https://issues.jboss.org/browse/DROOLS-1130
Project: Drools
Issue Type: Bug
Affects Versions: 6.3.0.Final
Reporter: Juan Carlos Garcia
Assignee: Mario Fusco
Attachments: timer-rule-bug.zip
I have a DRL file with 2 rules and the first rule has a timer of 3s, after this rule gets
fired and a fact is modified, i expect a second rule to get activate and trigger but is
not happening. Even though the documentation explicitly said in the 2.9.2 section of:
http://docs.jboss.org/drools/release/6.3.0.Final/drools-docs/html/ch02.ht...
_When the rule engine runs in passive mode (i.e.: using fireAllRules) by default it
doesn't fire consequences of timed rules unless fireAllRules isn't invoked again.
Now it is possible to change this default behavior by configuring the KieSession with a
*TimedRuleExectionOption*_
Please advise if i have misunderstood the expected behavior, attached is a demo project
enclosing the mentioned rules and a testcase.
*DRL:*
{code}
import java.util.logging.Logger
import bug.timedrules.Table
rule "table with 1 player"
timer( int: 3s)
no-loop true
when
$table : Table( getCounter() == 1)
then
Logger.getLogger("timer.drl").info("triggered - counter is 1");
modify($table){
setCounter(2)
}
end
rule "Table upgrade to 2 player"
no-loop true
when
$table : Table( getCounter() == 2)
then
Logger.getLogger("timer.drl").info("triggered - counter is 2");
modify($table){
setCounter(3)
}
end
{code}
*java code:*
{code}
@Test
public void executeNewRuleAfterTimedRuleExecution() throws Exception {
KieBaseConfiguration config =
KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
KieSessionConfiguration ksconf =
KieServices.Factory.get().newKieSessionConfiguration();
ksconf.setOption(TimedRuleExectionOption.YES);
config.setOption(EventProcessingOption.STREAM);
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(config);
final KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("bug/timer/timer.drl",
BugTest.class), ResourceType.DRL);
if (kbuilder.hasErrors()) {
throw new IllegalStateException(kbuilder.getErrors().toString());
}
kbase = KnowledgeBaseFactory.newKnowledgeBase(config);
kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
final StatefulKnowledgeSession statefulKnowledgeSession =
kbase.newStatefulKnowledgeSession(ksconf, null);
Table table = new Table(1234, 1);
statefulKnowledgeSession.insert(table);
statefulKnowledgeSession.fireAllRules();
Thread.sleep(TimeUnit.SECONDS.toMillis(5));
statefulKnowledgeSession.dispose();
Assert.assertThat(table.getCounter(), CoreMatchers.is(3));
}
{code}