Skip to content

Commit

Permalink
[BZ-1059372] avoid NPE in timer node when a tuple is activated and re…
Browse files Browse the repository at this point in the history
…scheduled in same node evaluation
  • Loading branch information
mariofusco committed Jan 29, 2014
1 parent 5dcf4be commit 5af33eb
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 7 deletions.
Expand Up @@ -45,6 +45,7 @@
import org.kie.api.runtime.conf.ClockTypeOption;
import org.kie.api.time.Calendar;
import org.kie.api.time.SessionClock;
import org.kie.internal.runtime.StatefulKnowledgeSession;

public class TimerAndCalendarTest extends CommonTestMethodBase {

Expand Down Expand Up @@ -1624,5 +1625,27 @@ public void testExpiredPropagations() throws InterruptedException {
ksession.dispose();
}

@Test
public void testCronFire() throws InterruptedException {
// BZ-1059372
String drl = "package test.drools\n" +
"rule TestRule " +
" timer (cron:* * * * * ?) " +
"when\n" +
" String() " +
" Integer() " +
"then\n" +
"end\n";

KnowledgeBase kbase = loadKnowledgeBaseFromString(drl);
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();

int repetitions = 10000;
for (int j = 0; j < repetitions; j++ ) {
ksession.insert( j );
}

ksession.insert( "go" );
ksession.fireAllRules();
}
}
Expand Up @@ -286,7 +286,12 @@ private void scheduleTimer(TimerNode timerNode,
if ( log.isTraceEnabled() ) {
log.trace( "Timer Fire Now {}", leftTuple );
}
doPropagateChildLeftTuple( sink, trgLeftTuples, stagedLeftTuples, leftTuple, tm );
LeftTuple childLeftTuple = doPropagateChildLeftTuple( sink, trgLeftTuples, stagedLeftTuples, leftTuple, tm );
if (childLeftTuple.getStagedType() == LeftTuple.INSERT) {
// Flag the newly created childLeftTuple to avoid a reevaluation in case it gets
// rescheduled before the end of this doNode loop
childLeftTuple.setObject(Boolean.TRUE);
}

trigger.nextFireTime();

Expand Down Expand Up @@ -336,18 +341,21 @@ public static void doPropagateChildLeftTuples(TimerNode timerNode,
}
}

private static void doPropagateChildLeftTuple(LeftTupleSink sink,
LeftTupleSets trgLeftTuples,
LeftTupleSets stagedLeftTuples,
LeftTuple leftTuple,
TimerNodeMemory tm) {
private static LeftTuple doPropagateChildLeftTuple(LeftTupleSink sink,
LeftTupleSets trgLeftTuples,
LeftTupleSets stagedLeftTuples,
LeftTuple leftTuple,
TimerNodeMemory tm) {
LeftTuple childLeftTuple = leftTuple.getFirstChild();
if ( childLeftTuple == null ) {
childLeftTuple = sink.createLeftTuple( leftTuple, sink, leftTuple.getPropagationContext(), true );
trgLeftTuples.addInsert( childLeftTuple );
trgLeftTuples.addInsert(childLeftTuple);
if ( log.isTraceEnabled() ) {
log.trace( "Timer Insert {}", childLeftTuple );
}
} else if (childLeftTuple.getObject() == Boolean.TRUE) {
// This childLeftTuple has been created in this doNode loop, just skip it
childLeftTuple.setObject(null);
} else {
switch ( childLeftTuple.getStagedType() ) {
// handle clash with already staged entries
Expand All @@ -363,6 +371,7 @@ private static void doPropagateChildLeftTuple(LeftTupleSink sink,
log.trace( "Timer Update {}", childLeftTuple );
}
}
return childLeftTuple;
}

public static class TimerNodeJob
Expand Down

0 comments on commit 5af33eb

Please sign in to comment.