LeftTupleList leftTuples = tm.getInsertOrUpdateLeftTuples();
synchronized ( leftTuples ) {
LeftTupleList deletes = tm.getDeleteLeftTuples();
if ( !deletes.isEmpty() ) {
for ( LeftTuple leftTuple = deletes.getFirst(); leftTuple != null; ) {
LeftTuple next = (LeftTuple) leftTuple.getNext();
srcLeftTuples.addDelete( leftTuple );
if ( log.isTraceEnabled() ) {
log.trace( "Timer Add Postponed Delete {}", leftTuple );
}
leftTuple.clear();
leftTuple = next;
}
deletes.clear();
}
for ( LeftTuple leftTuple = srcLeftTuples.getDeleteFirst(); leftTuple != null; ) {
LeftTuple next = leftTuple.getStagedNext();
DefaultJobHandle jobHandle = (DefaultJobHandle) leftTuple.getObject();
if ( jobHandle != null ) {
// jobHandle can be null, if the time fired straight away, and never ended up scheduling a job
timerService.removeJob( jobHandle );
}
org.drools.core.spi.PropagationContext pctx = leftTuple.getPropagationContext();
pctx = RuleTerminalNode.findMostRecentPropagationContext( leftTuple, pctx );
if ( leftTuple.getMemory() != null ) {
leftTuples.remove( leftTuple ); // it gets removed either way.
if ( pctx.getType() == PropagationContext.EXPIRATION ) {
// a expire clashes with insert or update, allow it to propagate once, will handle the expire the second time around
doPropagateChildLeftTuple( sink, trgLeftTuples, stagedLeftTuples, leftTuple, tm );
tm.getDeleteLeftTuples().add( leftTuple );
pmem.doLinkRule( wm ); // make sure it's dirty, so it'll evaluate again
if ( log.isTraceEnabled() ) {
log.trace( "Timer Postponed Delete {}", leftTuple );
}
}
}
if ( leftTuple.getMemory() == null ) {
// if it's != null, then it's already been postponed, and the existing child propagated
LeftTuple childLeftTuple = leftTuple.getFirstChild(); // only has one child
if ( childLeftTuple != null ) {
switch ( childLeftTuple.getStagedType() ) {
// handle clash with already staged entries
case LeftTuple.INSERT :
stagedLeftTuples.removeInsert( childLeftTuple );
break;
case LeftTuple.UPDATE :
stagedLeftTuples.removeUpdate( childLeftTuple );
break;
}
childLeftTuple.setPropagationContext( leftTuple.getPropagationContext() );
trgLeftTuples.addDelete( childLeftTuple );
if ( log.isTraceEnabled() ) {
log.trace( "Timer Delete {}", leftTuple );
}
}