[jboss-svn-commits] JBL Code SVN: r27318 - in labs/jbossrules/trunk: drools-compiler/src/test/java/org/drools/integrationtests and 3 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Mon Jun 29 21:10:21 EDT 2009
Author: tirelli
Date: 2009-06-29 21:10:21 -0400 (Mon, 29 Jun 2009)
New Revision: 27318
Modified:
labs/jbossrules/trunk/drools-clips/src/main/java/org/drools/clips/ClipsShell.java
labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/RulebasePartitioningTest.java
labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/testframework/MockWorkingMemory.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultAgenda.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalWorkingMemory.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/NamedEntryPoint.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooWorkingMemory.java
Log:
Adding support to idle time. I don't remember the ticket number and obviously enough, JIRA is down
Modified: labs/jbossrules/trunk/drools-clips/src/main/java/org/drools/clips/ClipsShell.java
===================================================================
--- labs/jbossrules/trunk/drools-clips/src/main/java/org/drools/clips/ClipsShell.java 2009-06-30 00:33:17 UTC (rev 27317)
+++ labs/jbossrules/trunk/drools-clips/src/main/java/org/drools/clips/ClipsShell.java 2009-06-30 01:10:21 UTC (rev 27318)
@@ -365,7 +365,7 @@
}
builder.append( "}" );
- functionDescr.setContent( builder.toString() );
+ functionDescr.setText( builder.toString() );
functionDescr.setDialect( "clips" );
PackageDescr pkgDescr = createPackageDescr( functionDescr.getNamespace() );
Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/RulebasePartitioningTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/RulebasePartitioningTest.java 2009-06-30 00:33:17 UTC (rev 27317)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/RulebasePartitioningTest.java 2009-06-30 01:10:21 UTC (rev 27318)
@@ -46,14 +46,7 @@
config );
}
- public void testDummy() {
- // I've added this until edson stops sucking.
- }
-
- /**
- * Edson Sucks so I'm making this a @FIXME
- */
- public void FIXME_testRulebasePartitions1() throws Exception {
+ public void testRulebasePartitions1() throws Exception {
final PackageBuilder builder = new PackageBuilder();
builder.addPackageFromDrl( new InputStreamReader( getClass().getResourceAsStream( "test_rulebasePartitions1.drl" ) ) );
final org.drools.rule.Package pkg = builder.getPackage();
Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/testframework/MockWorkingMemory.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/testframework/MockWorkingMemory.java 2009-06-30 00:33:17 UTC (rev 27317)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/testframework/MockWorkingMemory.java 2009-06-30 01:10:21 UTC (rev 27318)
@@ -562,4 +562,19 @@
return null;
}
+ public void endOperation() {
+ // TODO Auto-generated method stub
+
+ }
+
+ public long getIdleTime() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public void startOperation() {
+ // TODO Auto-generated method stub
+
+ }
+
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java 2009-06-30 00:33:17 UTC (rev 27317)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java 2009-06-30 01:10:21 UTC (rev 27318)
@@ -214,6 +214,13 @@
private Environment environment;
private ExecutionResults batchExecutionResult;
+
+ // this is a counter of concurrent operations happening. When this counter is zero,
+ // the engine is idle.
+ private AtomicLong opCounter;
+ // this is the timestamp of the end of the last operation, based on the session clock,
+ // or -1 if there are operation being executed at this moment
+ private AtomicLong lastIdleTimestamp;
// ------------------------------------------------------------
// Constructors
@@ -325,6 +332,9 @@
initProcessEventListeners();
initPartitionManagers();
initTransient();
+
+ this.opCounter = new AtomicLong(0);
+ this.lastIdleTimestamp = new AtomicLong( -1 );
}
public static class GlobalsAdapter
@@ -398,27 +408,37 @@
* running in multi-thread mode
*/
public void startPartitionManagers() {
- if ( this.ruleBase.getConfiguration().isMultithreadEvaluation() ) {
- int maxThreads = (this.ruleBase.getConfiguration().getMaxThreads() > 0) ? this.ruleBase.getConfiguration().getMaxThreads() : this.ruleBase.getPartitionIds().size();
- if ( this.threadPool.compareAndSet( null,
- Executors.newFixedThreadPool( maxThreads ) ) ) {
- for ( PartitionTaskManager task : this.partitionManagers.values() ) {
- task.setPool( this.threadPool.get() );
+ startOperation();
+ try {
+ if ( this.ruleBase.getConfiguration().isMultithreadEvaluation() ) {
+ int maxThreads = (this.ruleBase.getConfiguration().getMaxThreads() > 0) ? this.ruleBase.getConfiguration().getMaxThreads() : this.ruleBase.getPartitionIds().size();
+ if ( this.threadPool.compareAndSet( null,
+ Executors.newFixedThreadPool( maxThreads ) ) ) {
+ for ( PartitionTaskManager task : this.partitionManagers.values() ) {
+ task.setPool( this.threadPool.get() );
+ }
}
}
+ } finally {
+ endOperation();
}
}
public void stopPartitionManagers() {
- if ( this.ruleBase.getConfiguration().isMultithreadEvaluation() ) {
- java.util.concurrent.ExecutorService service = this.threadPool.get();
- if ( this.threadPool.compareAndSet( service,
- null ) ) {
- service.shutdown();
- for ( PartitionTaskManager task : this.partitionManagers.values() ) {
- task.setPool( null );
+ startOperation();
+ try {
+ if ( this.ruleBase.getConfiguration().isMultithreadEvaluation() ) {
+ java.util.concurrent.ExecutorService service = this.threadPool.get();
+ if ( this.threadPool.compareAndSet( service,
+ null ) ) {
+ service.shutdown();
+ for ( PartitionTaskManager task : this.partitionManagers.values() ) {
+ task.setPool( null );
+ }
}
}
+ } finally {
+ endOperation();
}
}
@@ -448,6 +468,8 @@
this.actionQueue.clear();
this.propagationIdCounter = new AtomicLong( propagationCounter );
+ this.opCounter.set( 0 );
+ this.lastIdleTimestamp.set( -1 );
// TODO should these be cleared?
// we probably neeed to do CEP and Flow timers too
@@ -542,6 +564,7 @@
try {
this.ruleBase.readLock();
this.lock.lock();
+ startOperation();
// Make sure the global has been declared in the RuleBase
final Map globalDefintions = this.ruleBase.getGlobals();
final Class type = (Class) globalDefintions.get( identifier );
@@ -555,6 +578,7 @@
value );
}
} finally {
+ endOperation();
this.lock.unlock();
this.ruleBase.readUnlock();
}
@@ -850,169 +874,175 @@
return null;
}
- ObjectTypeConf typeConf = this.typeConfReg.getObjectTypeConf( this.entryPoint,
- object );
-
- InternalFactHandle handle = null;
-
- if ( isSequential() ) {
- handle = createHandle( object,
- typeConf );
- insert( handle,
- object,
- rule,
- activation,
- typeConf );
- return handle;
- }
-
try {
- this.ruleBase.readLock();
- this.lock.lock();
- // check if the object already exists in the WM
- handle = (InternalFactHandle) this.objectStore.getHandleForObject( object );
+ startOperation();
+
+ ObjectTypeConf typeConf = this.typeConfReg.getObjectTypeConf( this.entryPoint,
+ object );
- if ( this.maintainTms ) {
+ InternalFactHandle handle = null;
- EqualityKey key = null;
+ if ( isSequential() ) {
+ handle = createHandle( object,
+ typeConf );
+ insert( handle,
+ object,
+ rule,
+ activation,
+ typeConf );
+ return handle;
+ }
+ try {
+ this.ruleBase.readLock();
+ this.lock.lock();
+ // check if the object already exists in the WM
+ handle = (InternalFactHandle) this.objectStore.getHandleForObject( object );
- if ( handle == null ) {
- // lets see if the object is already logical asserted
- key = this.tms.get( object );
- } else {
- // Object is already asserted, so check and possibly correct
- // its
- // status and then return the handle
- key = handle.getEqualityKey();
+ if ( this.maintainTms ) {
- if ( key.getStatus() == EqualityKey.STATED ) {
- // return null as you cannot justify a stated object.
- return handle;
- }
+ EqualityKey key = null;
- if ( !logical ) {
- // this object was previously justified, so we have to
- // override it to stated
- key.setStatus( EqualityKey.STATED );
- this.tms.removeLogicalDependencies( handle );
+ if ( handle == null ) {
+ // lets see if the object is already logical asserted
+ key = this.tms.get( object );
} else {
- // this was object is already justified, so just add new
- // logical dependency
- this.tms.addLogicalDependency( handle,
- activation,
- activation.getPropagationContext(),
- rule );
- }
+ // Object is already asserted, so check and possibly correct
+ // its
+ // status and then return the handle
+ key = handle.getEqualityKey();
- return handle;
- }
+ if ( key.getStatus() == EqualityKey.STATED ) {
+ // return null as you cannot justify a stated object.
+ return handle;
+ }
- // At this point we know the handle is null
- if ( key == null ) {
- handle = createHandle( object,
- typeConf );
+ if ( !logical ) {
+ // this object was previously justified, so we have to
+ // override it to stated
+ key.setStatus( EqualityKey.STATED );
+ this.tms.removeLogicalDependencies( handle );
+ } else {
+ // this was object is already justified, so just add new
+ // logical dependency
+ this.tms.addLogicalDependency( handle,
+ activation,
+ activation.getPropagationContext(),
+ rule );
+ }
- key = new EqualityKey( handle );
- handle.setEqualityKey( key );
- this.tms.put( key );
- if ( !logical ) {
- key.setStatus( EqualityKey.STATED );
- } else {
- key.setStatus( EqualityKey.JUSTIFIED );
- this.tms.addLogicalDependency( handle,
- activation,
- activation.getPropagationContext(),
- rule );
+ return handle;
}
- } else if ( !logical ) {
- if ( key.getStatus() == EqualityKey.JUSTIFIED ) {
- // Its previous justified, so switch to stated and
- // remove
- // logical dependencies
- final InternalFactHandle justifiedHandle = key.getFactHandle();
- this.tms.removeLogicalDependencies( justifiedHandle );
- if ( this.discardOnLogicalOverride ) {
- // override, setting to new instance, and return
- // existing handle
+ // At this point we know the handle is null
+ if ( key == null ) {
+ handle = createHandle( object,
+ typeConf );
+
+ key = new EqualityKey( handle );
+ handle.setEqualityKey( key );
+ this.tms.put( key );
+ if ( !logical ) {
key.setStatus( EqualityKey.STATED );
- handle = key.getFactHandle();
+ } else {
+ key.setStatus( EqualityKey.JUSTIFIED );
+ this.tms.addLogicalDependency( handle,
+ activation,
+ activation.getPropagationContext(),
+ rule );
+ }
+ } else if ( !logical ) {
+ if ( key.getStatus() == EqualityKey.JUSTIFIED ) {
+ // Its previous justified, so switch to stated and
+ // remove
+ // logical dependencies
+ final InternalFactHandle justifiedHandle = key.getFactHandle();
+ this.tms.removeLogicalDependencies( justifiedHandle );
- if ( AssertBehaviour.IDENTITY.equals( this.ruleBase.getConfiguration().getAssertBehaviour() ) ) {
- // as assertMap may be using an "identity"
- // equality comparator,
- // we need to remove the handle from the map,
- // before replacing the object
- // and then re-add the handle. Otherwise we may
- // end up with a leak.
- this.objectStore.updateHandle( handle,
- object );
+ if ( this.discardOnLogicalOverride ) {
+ // override, setting to new instance, and return
+ // existing handle
+ key.setStatus( EqualityKey.STATED );
+ handle = key.getFactHandle();
+
+ if ( AssertBehaviour.IDENTITY.equals( this.ruleBase.getConfiguration().getAssertBehaviour() ) ) {
+ // as assertMap may be using an "identity"
+ // equality comparator,
+ // we need to remove the handle from the map,
+ // before replacing the object
+ // and then re-add the handle. Otherwise we may
+ // end up with a leak.
+ this.objectStore.updateHandle( handle,
+ object );
+ } else {
+ Object oldObject = handle.getObject();
+ }
+ return handle;
} else {
- Object oldObject = handle.getObject();
+ // override, then instantiate new handle for
+ // assertion
+ key.setStatus( EqualityKey.STATED );
+ handle = createHandle( object,
+ typeConf );
+ handle.setEqualityKey( key );
+ key.addFactHandle( handle );
}
- return handle;
+
} else {
- // override, then instantiate new handle for
- // assertion
- key.setStatus( EqualityKey.STATED );
handle = createHandle( object,
typeConf );
+ key.addFactHandle( handle );
handle.setEqualityKey( key );
- key.addFactHandle( handle );
+
}
} else {
- handle = createHandle( object,
- typeConf );
- key.addFactHandle( handle );
- handle.setEqualityKey( key );
-
+ if ( key.getStatus() == EqualityKey.JUSTIFIED ) {
+ // only add as logical dependency if this wasn't
+ // previously
+ // stated
+ this.tms.addLogicalDependency( key.getFactHandle(),
+ activation,
+ activation.getPropagationContext(),
+ rule );
+ return key.getFactHandle();
+ } else {
+ // You cannot justify a previously stated equality equal
+ // object, so return null
+ return null;
+ }
}
} else {
- if ( key.getStatus() == EqualityKey.JUSTIFIED ) {
- // only add as logical dependency if this wasn't
- // previously
- // stated
- this.tms.addLogicalDependency( key.getFactHandle(),
- activation,
- activation.getPropagationContext(),
- rule );
- return key.getFactHandle();
- } else {
- // You cannot justify a previously stated equality equal
- // object, so return null
- return null;
+ if ( handle != null ) {
+ return handle;
}
+ handle = createHandle( object,
+ typeConf );
+
}
- } else {
- if ( handle != null ) {
- return handle;
+ // if the dynamic parameter is true or if the
+ // user declared the fact type with the meta tag:
+ // @propertyChangeSupport
+ if ( dynamic || typeConf.isDynamic() ) {
+ addPropertyChangeListener( object );
}
- handle = createHandle( object,
- typeConf );
- }
+ insert( handle,
+ object,
+ rule,
+ activation,
+ typeConf );
- // if the dynamic parameter is true or if the
- // user declared the fact type with the meta tag:
- // @propertyChangeSupport
- if ( dynamic || typeConf.isDynamic() ) {
- addPropertyChangeListener( object );
+ } finally {
+ this.lock.unlock();
+ this.ruleBase.readUnlock();
}
-
- insert( handle,
- object,
- rule,
- activation,
- typeConf );
-
+ return handle;
} finally {
- this.lock.unlock();
- this.ruleBase.readUnlock();
+ endOperation();
}
- return handle;
+
}
private InternalFactHandle createHandle(final Object object,
@@ -1130,6 +1160,7 @@
try {
this.ruleBase.readLock();
this.lock.lock();
+ startOperation();
this.ruleBase.executeQueuedActions();
InternalFactHandle handle = (InternalFactHandle) factHandle;
@@ -1198,6 +1229,7 @@
executeQueuedActions();
} finally {
+ endOperation();
this.lock.unlock();
this.ruleBase.readUnlock();
}
@@ -1215,6 +1247,7 @@
try {
this.ruleBase.readLock();
this.lock.lock();
+ startOperation();
this.ruleBase.executeQueuedActions();
InternalFactHandle handle = (InternalFactHandle) factHandle;
@@ -1268,6 +1301,7 @@
}
}
} finally {
+ endOperation();
this.lock.unlock();
this.ruleBase.readUnlock();
}
@@ -1288,6 +1322,7 @@
try {
this.ruleBase.readLock();
this.lock.lock();
+ startOperation();
this.ruleBase.executeQueuedActions();
InternalFactHandle handle = (InternalFactHandle) factHandle;
@@ -1344,6 +1379,7 @@
executeQueuedActions();
} finally {
+ endOperation();
this.lock.unlock();
this.ruleBase.readUnlock();
}
@@ -1381,6 +1417,7 @@
try {
this.ruleBase.readLock();
this.lock.lock();
+ startOperation();
this.ruleBase.executeQueuedActions();
// the handle might have been disconnected, so reconnect if it has
@@ -1478,33 +1515,39 @@
executeQueuedActions();
} finally {
+ endOperation();
this.lock.unlock();
this.ruleBase.readUnlock();
}
}
public void executeQueuedActions() {
- synchronized ( this.actionQueue ) {
- if ( !this.actionQueue.isEmpty() && !evaluatingActionQueue ) {
- evaluatingActionQueue = true;
- WorkingMemoryAction action = null;
+ try {
+ startOperation();
+ synchronized ( this.actionQueue ) {
+ if ( !this.actionQueue.isEmpty() && !evaluatingActionQueue ) {
+ evaluatingActionQueue = true;
+ WorkingMemoryAction action = null;
- while ( (action = actionQueue.poll()) != null ) {
- try {
- action.execute( this );
- } catch ( Exception e ) {
- if ( e instanceof RuntimeDroolsException ) {
- // rethrow the exception
- throw ((RuntimeDroolsException) e);
- } else {
- System.err.println( "************************************************" );
- System.err.println( "Exception caught while executing action: " + action.toString() );
- e.printStackTrace();
+ while ( (action = actionQueue.poll()) != null ) {
+ try {
+ action.execute( this );
+ } catch ( Exception e ) {
+ if ( e instanceof RuntimeDroolsException ) {
+ // rethrow the exception
+ throw ((RuntimeDroolsException) e);
+ } else {
+ System.err.println( "************************************************" );
+ System.err.println( "Exception caught while executing action: " + action.toString() );
+ e.printStackTrace();
+ }
}
}
+ evaluatingActionQueue = false;
}
- evaluatingActionQueue = false;
}
+ } finally {
+ endOperation();
}
}
@@ -1615,22 +1658,27 @@
public ProcessInstance startProcess(String processId,
Map<String, Object> parameters) {
- if ( !this.actionQueue.isEmpty() ) {
- executeQueuedActions();
+ try {
+ startOperation();
+ if ( !this.actionQueue.isEmpty() ) {
+ executeQueuedActions();
+ }
+ final Process process = ((InternalRuleBase) getRuleBase()).getProcess( processId );
+ if ( process == null ) {
+ throw new IllegalArgumentException( "Unknown process ID: " + processId );
+ }
+ ProcessInstance processInstance = startProcess( process, parameters );
+
+ if (processInstance != null) {
+ // start process instance
+ getRuleFlowEventSupport().fireBeforeRuleFlowProcessStarted( processInstance, this );
+ processInstance.start();
+ getRuleFlowEventSupport().fireAfterRuleFlowProcessStarted( processInstance, this );
+ }
+ return processInstance;
+ } finally {
+ endOperation();
}
- final Process process = ((InternalRuleBase) getRuleBase()).getProcess( processId );
- if ( process == null ) {
- throw new IllegalArgumentException( "Unknown process ID: " + processId );
- }
- ProcessInstance processInstance = startProcess( process, parameters );
-
- if (processInstance != null) {
- // start process instance
- getRuleFlowEventSupport().fireBeforeRuleFlowProcessStarted( processInstance, this );
- processInstance.start();
- getRuleFlowEventSupport().fireAfterRuleFlowProcessStarted( processInstance, this );
- }
- return processInstance;
}
private ProcessInstance startProcess(final Process process, Map<String, Object> parameters) {
@@ -1948,5 +1996,48 @@
public Map<String, WorkingMemoryEntryPoint> getEntryPoints() {
return this.entryPoints;
}
+
+ /**
+ * This method must be called before starting any new work in the engine,
+ * like inserting a new fact or firing a new rule. It will reset the engine
+ * idle time counter.
+ *
+ * This method must be extremely light to avoid contentions when called by
+ * multiple threads/entry-points
+ */
+ public void startOperation() {
+ if( this.opCounter.getAndIncrement() == 0) {
+ // means the engine was idle, reset the timestamp
+ this.lastIdleTimestamp.set( -1 );
+ }
+ }
+ /**
+ * This method must be called after finishing any work in the engine,
+ * like inserting a new fact or firing a new rule. It will reset the engine
+ * idle time counter.
+ *
+ * This method must be extremely light to avoid contentions when called by
+ * multiple threads/entry-points
+ */
+ public void endOperation() {
+ if( this.opCounter.decrementAndGet() == 0) {
+ // means the engine is idle, so, set the timestamp
+ this.lastIdleTimestamp.set( this.timerManager.getTimerService().getCurrentTime() );
+ }
+ }
+
+ /**
+ * Returns the number of time units (usually ms) that the engine is idle
+ * according to the session clock or -1 if it is not idle.
+ *
+ * This method is not synchronised and might return an approximate value.
+ *
+ * @return
+ */
+ public long getIdleTime() {
+ long lastIdle = this.lastIdleTimestamp.get();
+ return lastIdle > -1 ? timerManager.getTimerService().getCurrentTime() - lastIdle : -1;
+ }
+
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultAgenda.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultAgenda.java 2009-06-30 00:33:17 UTC (rev 27317)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultAgenda.java 2009-06-30 01:10:21 UTC (rev 27318)
@@ -912,69 +912,74 @@
// We do this first as if a node modifies a fact that causes a recursion
// on an empty pattern
// we need to make sure it re-activates
- increaseDormantActivations();
+ this.workingMemory.startOperation();
+ try {
+ increaseDormantActivations();
- final EventSupport eventsupport = (EventSupport) this.workingMemory;
+ final EventSupport eventsupport = (EventSupport) this.workingMemory;
- eventsupport.getAgendaEventSupport().fireBeforeActivationFired( activation,
- this.workingMemory );
+ eventsupport.getAgendaEventSupport().fireBeforeActivationFired( activation,
+ this.workingMemory );
- if ( activation.getActivationGroupNode() != null ) {
- // We know that this rule will cancel all other activatiosn in the
- // group
- // so lets remove the information now, before the consequence fires
- final ActivationGroup activationGroup = activation.getActivationGroupNode().getActivationGroup();
- activationGroup.removeActivation( activation );
- clearAndCancelActivationGroup( activationGroup );
- }
- activation.setActivated( false );
+ if ( activation.getActivationGroupNode() != null ) {
+ // We know that this rule will cancel all other activatiosn in the
+ // group
+ // so lets remove the information now, before the consequence fires
+ final ActivationGroup activationGroup = activation.getActivationGroupNode().getActivationGroup();
+ activationGroup.removeActivation( activation );
+ clearAndCancelActivationGroup( activationGroup );
+ }
+ activation.setActivated( false );
- try {
- this.knowledgeHelper.setActivation( activation );
- activation.getRule().getConsequence().evaluate( this.knowledgeHelper,
- this.workingMemory );
- this.knowledgeHelper.reset();
- } catch ( final Exception e ) {
- if ( this.legacyConsequenceExceptionHandler != null ) {
- this.legacyConsequenceExceptionHandler.handleException( activation,
- this.workingMemory,
- e );
- } else if ( this.consequenceExceptionHandler != null ) {
- this.consequenceExceptionHandler.handleException( activation,
- new StatefulKnowledgeSessionImpl( (ReteooWorkingMemory) this.workingMemory ),
- e );
- } else {
- throw new RuntimeException( e );
+ try {
+ this.knowledgeHelper.setActivation( activation );
+ activation.getRule().getConsequence().evaluate( this.knowledgeHelper,
+ this.workingMemory );
+ this.knowledgeHelper.reset();
+ } catch ( final Exception e ) {
+ if ( this.legacyConsequenceExceptionHandler != null ) {
+ this.legacyConsequenceExceptionHandler.handleException( activation,
+ this.workingMemory,
+ e );
+ } else if ( this.consequenceExceptionHandler != null ) {
+ this.consequenceExceptionHandler.handleException( activation,
+ new StatefulKnowledgeSessionImpl( (ReteooWorkingMemory) this.workingMemory ),
+ e );
+ } else {
+ throw new RuntimeException( e );
+ }
}
- }
- if ( activation.getRuleFlowGroupNode() != null ) {
- final InternalRuleFlowGroup ruleFlowGroup = activation.getRuleFlowGroupNode().getRuleFlowGroup();
- // it is possible that the ruleflow group is no longer active if it was
- // cleared during execution of this activation
- if (ruleFlowGroup.isActive()) {
- ruleFlowGroup.removeActivation( activation );
+ if ( activation.getRuleFlowGroupNode() != null ) {
+ final InternalRuleFlowGroup ruleFlowGroup = activation.getRuleFlowGroupNode().getRuleFlowGroup();
+ // it is possible that the ruleflow group is no longer active if it was
+ // cleared during execution of this activation
+ if (ruleFlowGroup.isActive()) {
+ ruleFlowGroup.removeActivation( activation );
+ }
}
- }
- // if the tuple contains expired events
- for ( LeftTuple tuple = (LeftTuple) activation.getTuple(); tuple != null; tuple = tuple.getParent() ) {
- if ( tuple.getLastHandle().isEvent() ) {
- EventFactHandle handle = (EventFactHandle) tuple.getLastHandle();
- // handles "expire" only in stream mode.
- if ( handle.isExpired() ) {
- // decrease the activation count for the event
- handle.decreaseActivationsCount();
- if ( handle.getActivationsCount() == 0 ) {
- // and if no more activations, retract the handle
- handle.getEntryPoint().retract( handle );
+ // if the tuple contains expired events
+ for ( LeftTuple tuple = (LeftTuple) activation.getTuple(); tuple != null; tuple = tuple.getParent() ) {
+ if ( tuple.getLastHandle().isEvent() ) {
+ EventFactHandle handle = (EventFactHandle) tuple.getLastHandle();
+ // handles "expire" only in stream mode.
+ if ( handle.isExpired() ) {
+ // decrease the activation count for the event
+ handle.decreaseActivationsCount();
+ if ( handle.getActivationsCount() == 0 ) {
+ // and if no more activations, retract the handle
+ handle.getEntryPoint().retract( handle );
+ }
}
}
}
+
+ eventsupport.getAgendaEventSupport().fireAfterActivationFired( activation,
+ this.workingMemory );
+ } finally {
+ this.workingMemory.endOperation();
}
-
- eventsupport.getAgendaEventSupport().fireAfterActivationFired( activation,
- this.workingMemory );
}
public void increaseActiveActivations() {
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalWorkingMemory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalWorkingMemory.java 2009-06-30 00:33:17 UTC (rev 27317)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalWorkingMemory.java 2009-06-30 01:10:21 UTC (rev 27318)
@@ -139,4 +139,35 @@
public BatchExecutionResultImpl getExecutionResult();
public void endBatchExecution();
+
+ /**
+ * This method must be called before starting any new work in the engine,
+ * like inserting a new fact or firing a new rule. It will reset the engine
+ * idle time counter.
+ *
+ * This method must be extremely light to avoid contentions when called by
+ * multiple threads/entry-points
+ */
+ public void startOperation();
+
+ /**
+ * This method must be called after finishing any work in the engine,
+ * like inserting a new fact or firing a new rule. It will reset the engine
+ * idle time counter.
+ *
+ * This method must be extremely light to avoid contentions when called by
+ * multiple threads/entry-points
+ */
+ public void endOperation();
+
+ /**
+ * Returns the number of time units (usually ms) that the engine is idle
+ * according to the session clock or -1 if it is not idle.
+ *
+ * This method is not synchronised and might return an approximate value.
+ *
+ * @return
+ */
+ public long getIdleTime();
+
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/NamedEntryPoint.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/NamedEntryPoint.java 2009-06-30 00:33:17 UTC (rev 27317)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/NamedEntryPoint.java 2009-06-30 01:10:21 UTC (rev 27318)
@@ -102,32 +102,34 @@
// you cannot assert a null object
return null;
}
-
- ObjectTypeConf typeConf = this.typeConfReg.getObjectTypeConf( this.entryPoint,
- object );
-
- InternalFactHandle handle = this.handleFactory.newFactHandle( object,
- typeConf,
- wm );
- handle.setEntryPoint( this );
- this.objectStore.addHandle( handle,
- object );
-
- if ( dynamic ) {
- addPropertyChangeListener( object );
- }
-
+
try {
- this.lock.lock();
- insert( handle,
- object,
- rule,
- activation );
+ this.wm.startOperation();
+ ObjectTypeConf typeConf = this.typeConfReg.getObjectTypeConf( this.entryPoint,
+ object );
+ InternalFactHandle handle = this.handleFactory.newFactHandle( object,
+ typeConf,
+ wm );
+ handle.setEntryPoint( this );
+ this.objectStore.addHandle( handle,
+ object );
+ if ( dynamic ) {
+ addPropertyChangeListener( object );
+ }
+ try {
+ this.lock.lock();
+ insert( handle,
+ object,
+ rule,
+ activation );
+ } finally {
+ this.lock.unlock();
+ }
+ return handle;
} finally {
- this.lock.unlock();
+ this.wm.endOperation();
}
- return handle;
}
protected void insert(final InternalFactHandle handle,
@@ -178,6 +180,7 @@
try {
this.lock.lock();
this.ruleBase.executeQueuedActions();
+ this.wm.startOperation();
final InternalFactHandle handle = (InternalFactHandle) factHandle;
final Object originalObject = handle.getObject();
@@ -237,6 +240,7 @@
this.wm.executeQueuedActions();
} finally {
+ this.wm.endOperation();
this.lock.unlock();
}
}
@@ -257,6 +261,7 @@
try {
this.lock.lock();
this.ruleBase.executeQueuedActions();
+ this.wm.startOperation();
final InternalFactHandle handle = (InternalFactHandle) factHandle;
if ( handle.getId() == -1 ) {
@@ -299,6 +304,7 @@
this.wm.executeQueuedActions();
} finally {
+ this.wm.endOperation();
this.lock.unlock();
}
}
@@ -315,6 +321,7 @@
try {
this.lock.lock();
this.ruleBase.executeQueuedActions();
+ this.wm.startOperation();
final InternalFactHandle handle = (InternalFactHandle) factHandle;
// final Object originalObject = (handle.isShadowFact()) ?
@@ -350,6 +357,7 @@
this.wm );
} finally {
+ this.wm.endOperation();
this.lock.unlock();
}
}
@@ -381,6 +389,7 @@
try {
this.lock.lock();
this.ruleBase.executeQueuedActions();
+ this.wm.startOperation();
final InternalFactHandle handle = (InternalFactHandle) factHandle;
final Object originalObject = handle.getObject();
@@ -419,6 +428,7 @@
this.wm.executeQueuedActions();
} finally {
+ this.wm.endOperation();
this.lock.unlock();
}
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooWorkingMemory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooWorkingMemory.java 2009-06-30 00:33:17 UTC (rev 27317)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooWorkingMemory.java 2009-06-30 01:10:21 UTC (rev 27318)
@@ -45,7 +45,6 @@
import org.drools.rule.Rule;
import org.drools.runtime.Environment;
import org.drools.runtime.ObjectFilter;
-import org.drools.runtime.rule.FactHandle;
import org.drools.spi.FactHandleFactory;
import org.drools.spi.PropagationContext;
@@ -134,57 +133,62 @@
public QueryResults getQueryResults(final String query,
final Object[] arguments) {
- Object object = new DroolsQuery( query,
- arguments );
- InternalFactHandle handle = this.handleFactory.newFactHandle( object,
- this.getObjectTypeConfigurationRegistry().getObjectTypeConf( EntryPoint.DEFAULT,
- object ),
- this );
+ try {
+ startOperation();
+ Object object = new DroolsQuery( query,
+ arguments );
+ InternalFactHandle handle = this.handleFactory.newFactHandle( object,
+ this.getObjectTypeConfigurationRegistry().getObjectTypeConf( EntryPoint.DEFAULT,
+ object ),
+ this );
- insert( handle,
- object,
- null,
- null,
- this.typeConfReg.getObjectTypeConf( this.entryPoint,
- object ) );
+ insert( handle,
+ object,
+ null,
+ null,
+ this.typeConfReg.getObjectTypeConf( this.entryPoint,
+ object ) );
- final QueryTerminalNode node = (QueryTerminalNode) this.queryResults.remove( query );
- Query queryObj = null;
- List list = null;
+ final QueryTerminalNode node = (QueryTerminalNode) this.queryResults.remove( query );
+ Query queryObj = null;
+ List list = null;
- if ( node == null ) {
- // There are no results, first check the query object actually exists
- final org.drools.rule.Package[] pkgs = this.ruleBase.getPackages();
- for ( int i = 0; i < pkgs.length; i++ ) {
- final Rule rule = pkgs[i].getRule( query );
- if ( (rule != null) && (rule instanceof Query) ) {
- queryObj = (Query) rule;
- break;
+ if ( node == null ) {
+ // There are no results, first check the query object actually exists
+ final org.drools.rule.Package[] pkgs = this.ruleBase.getPackages();
+ for ( int i = 0; i < pkgs.length; i++ ) {
+ final Rule rule = pkgs[i].getRule( query );
+ if ( (rule != null) && (rule instanceof Query) ) {
+ queryObj = (Query) rule;
+ break;
+ }
}
- }
- this.handleFactory.destroyFactHandle( handle );
+ this.handleFactory.destroyFactHandle( handle );
- if ( queryObj == null ) {
- throw new IllegalArgumentException( "Query '" + query + "' does not exist" );
- }
- list = Collections.EMPTY_LIST;
- } else {
- list = (List) this.getNodeMemory( node );
-
- if ( list == null ) {
+ if ( queryObj == null ) {
+ throw new IllegalArgumentException( "Query '" + query + "' does not exist" );
+ }
list = Collections.EMPTY_LIST;
} else {
- this.clearNodeMemory( node );
+ list = (List) this.getNodeMemory( node );
+
+ if ( list == null ) {
+ list = Collections.EMPTY_LIST;
+ } else {
+ this.clearNodeMemory( node );
+ }
+ queryObj = (Query) node.getRule();
+
+ this.handleFactory.destroyFactHandle( handle );
}
- queryObj = (Query) node.getRule();
- this.handleFactory.destroyFactHandle( handle );
+ return new QueryResults( list,
+ queryObj,
+ this );
+ } finally {
+ endOperation();
}
-
- return new QueryResults( list,
- queryObj,
- this );
}
void setQueryResults(final String query,
More information about the jboss-svn-commits
mailing list