From: <jbo...@li...> - 2006-04-27 09:55:23
|
Author: mar...@jb... Date: 2006-04-27 05:55:10 -0400 (Thu, 27 Apr 2006) New Revision: 3992 Removed: labs/jbossrules/trunk/drools-core/src/main/java/org/objectweb/ Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/WorkingMemory.java labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AgendaEventSupport.java labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/WorkingMemoryEventSupport.java labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleBaseImpl.java labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/WorkingMemoryImpl.java Log: -Add Lock code. So that when we add a Package to RuleBaseImpl it doesn't udpate a working memory during a WMA. Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/WorkingMemory.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/WorkingMemory.java 2006-04-27 09:00:47 UTC (rev 3991) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/WorkingMemory.java 2006-04-27 09:55:10 UTC (rev 3992) @@ -93,7 +93,7 @@ Map getGlobals(); /** - * Set a specific piece of application data in this working memory + * Set a specific piece of global in this working memory. * * @param name * the name under which to populate the data @@ -104,7 +104,7 @@ Object value); /** - * Retrieve a specific piece of application data by name + * Retrieve a specific piece of global data by name * * @return application data or null if nothing is set under this name */ Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AgendaEventSupport.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AgendaEventSupport.java 2006-04-27 09:00:47 UTC (rev 3991) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/AgendaEventSupport.java 2006-04-27 09:55:10 UTC (rev 3992) @@ -33,7 +33,7 @@ public class AgendaEventSupport implements Serializable { - private final List listeners = new ArrayList(); + private final List listeners = Collections.synchronizedList( new ArrayList() ); private final WorkingMemory workingMemory; public AgendaEventSupport(WorkingMemory workingMemory) { Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/WorkingMemoryEventSupport.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/WorkingMemoryEventSupport.java 2006-04-27 09:00:47 UTC (rev 3991) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/WorkingMemoryEventSupport.java 2006-04-27 09:55:10 UTC (rev 3992) @@ -34,7 +34,7 @@ public class WorkingMemoryEventSupport implements Serializable { - private final List listeners = new ArrayList(); + private final List listeners = Collections.synchronizedList( new ArrayList() ); private final WorkingMemory workingMemory; public WorkingMemoryEventSupport(WorkingMemory workingMemory) { Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleBaseImpl.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleBaseImpl.java 2006-04-27 09:00:47 UTC (rev 3991) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleBaseImpl.java 2006-04-27 09:55:10 UTC (rev 3992) @@ -170,16 +170,16 @@ this.rete = (Rete) streamWithLoader.readObject(); this.reteooBuilder = (ReteooBuilder) streamWithLoader.readObject(); - + this.reteooBuilder.setRuleBase( this ); this.reteooBuilder.setRete( this.rete ); - + this.factHandleFactory = (FactHandleFactory) streamWithLoader.readObject(); this.globals = (Map) streamWithLoader.readObject(); this.workingMemories = new WeakHashMap(); this.lock = new Object(); - + } // ------------------------------------------------------------ @@ -306,10 +306,12 @@ /** * Add a <code>Package</code> to the network. Iterates through the * <code>Package</code> adding Each individual <code>Rule</code> to the - * network. + * network. Before update network each referenced <code>WorkingMemory</code> + * is locked. * * @param pkg - * The rule-set to add. + * The package to add. + * @throws PackageIntegrationException * * @throws RuleIntegrationException * if an error prevents complete construction of the network for @@ -317,12 +319,17 @@ * @throws FactException * @throws InvalidPatternException */ - public void addPackage(Package newPkg) throws RuleIntegrationException, - PackageIntegrationException, - FactException, - InvalidPatternException { + public void addPackage(Package newPkg) throws PackageIntegrationException { newPkg.checkValidity(); Package pkg = (Package) this.pkgs.get( newPkg.getName() ); + + // Iterate each workingMemory and lock it + // This is so we don't update the Rete network during propagation + for ( Iterator it = this.workingMemories.keySet().iterator(); it.hasNext(); ) { + WorkingMemoryImpl workingMemory = (WorkingMemoryImpl) it.next(); + workingMemory.getLock().lock(); + } + if ( pkg != null ) { mergePackage( pkg, newPkg ); @@ -351,10 +358,19 @@ } this.packageClassLoader.addClassLoader( newPkg.getPackageCompilationData().getClassLoader() ); + + // Iterate each workingMemory and attempt to fire any rules, that were activated as a result of the new rule addition + // + for ( Iterator it = this.workingMemories.keySet().iterator(); it.hasNext(); ) { + WorkingMemoryImpl workingMemory = (WorkingMemoryImpl) it.next(); + + workingMemory.fireAllRules(); + workingMemory.getLock().unlock(); + } } - public void mergePackage(Package pkg, - Package newPkg) throws PackageIntegrationException { + private void mergePackage(Package pkg, + Package newPkg) throws PackageIntegrationException { Map globals = pkg.getGlobals(); List imports = pkg.getImports(); @@ -385,21 +401,15 @@ } } - public void addRule(Rule rule) throws InvalidPatternException { - if ( !rule.isValid() ) throw new IllegalArgumentException( "The rule called " + rule.getName() + " is not valid. Check for compile errors reported." ); + private void addRule(Rule rule) throws InvalidPatternException { + if ( !rule.isValid() ) { + throw new IllegalArgumentException( "The rule called " + rule.getName() + " is not valid. Check for compile errors reported." ); + } - synchronized ( this.lock ) { - // This adds the rule. ReteBuilder has a reference to the WorkingMemories and will propagate any existing facts. - this.reteooBuilder.addRule( rule ); + // This adds the rule. ReteBuilder has a reference to the WorkingMemories and will propagate any existing facts. + this.reteooBuilder.addRule( rule ); + } - // Iterate each workingMemory and attempt to fire any rules, that were activated as a result of the new rule addition - for ( Iterator it = this.workingMemories.keySet().iterator(); it.hasNext(); ) { - WorkingMemoryImpl workingMemory = (WorkingMemoryImpl) it.next(); - workingMemory.fireAllRules(); - } - } - } - public void removePackage(String packageName) { Package pkg = (Package) this.pkgs.get( packageName ); Rule[] rules = pkg.getRules(); Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/WorkingMemoryImpl.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/WorkingMemoryImpl.java 2006-04-27 09:00:47 UTC (rev 3991) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/WorkingMemoryImpl.java 2006-04-27 09:55:10 UTC (rev 3992) @@ -58,6 +58,8 @@ import org.drools.util.IdentityMap; import org.drools.util.PrimitiveLongMap; import org.drools.util.PrimitiveLongStack; +import org.drools.util.concurrent.locks.Lock; +import org.drools.util.concurrent.locks.ReentrantLock; /** * Implementation of <code>WorkingMemory</code>. @@ -90,9 +92,9 @@ /** Global values which are associated with this memory. */ private final Map globals = new HashMap(); -// /** Handle-to-object mapping. */ -// private final PrimitiveLongMap objects = new PrimitiveLongMap( 32, -// 8 ); + // /** Handle-to-object mapping. */ + // private final PrimitiveLongMap objects = new PrimitiveLongMap( 32, + // 8 ); /** Object-to-handle mapping. */ private final Map identityMap = new IdentityMap(); @@ -117,7 +119,7 @@ //private LinkedList factQueue = new LinkedList(); - private Object lock = new Object(); + private ReentrantLock lock = new ReentrantLock(); /** The <code>RuleBase</code> with which this memory is associated. */ private final RuleBaseImpl ruleBase; @@ -200,10 +202,10 @@ * @see WorkingMemory */ public void setGlobal(String name, - Object value) { - // Make sure the application data has been declared in the RuleBase - Map applicationDataDefintions = this.ruleBase.getGlobals(); - Class type = (Class) applicationDataDefintions.get( name ); + Object value) { + // Make sure the global has been declared in the RuleBase + Map globalDefintions = this.ruleBase.getGlobals(); + Class type = (Class) globalDefintions.get( name ); if ( (type == null) ) { throw new RuntimeException( "Unexpected global [" + name + "]" ); } else if ( !type.isInstance( value ) ) { @@ -219,7 +221,8 @@ * @see WorkingMemory */ public Object getGlobal(String name) { - return this.globals.get( name ); + Object object = this.globals.get( name ); + return object; } /** @@ -246,6 +249,13 @@ return this.ruleBase; } + /** + * @see WorkingMemory + */ + public void fireAllRules() throws FactException { + fireAllRules( null ); + } + public synchronized void fireAllRules(AgendaFilter agendaFilter) throws FactException { // If we're already firing a rule, then it'll pick up // the firing for any other assertObject(..) that get @@ -266,13 +276,6 @@ } /** - * @see WorkingMemory - */ - public void fireAllRules() throws FactException { - fireAllRules( null ); - } - - /** * Returns the fact Object for the given <code>FactHandle</code>. It * actually attemps to return the value from the handle, before retrieving * it from objects map. @@ -286,14 +289,6 @@ */ public Object getObject(FactHandle handle) { InternalFactHandle handleImpl = (InternalFactHandle) handle; -// if ( handleImpl.getObject() == null ) { -// Object object = this.objects.get( handleImpl.getId() ); -// if ( object == null ) { -// throw new NoSuchFactObjectException( handle ); -// } -// handleImpl.setObject( object ); -// } - return handleImpl.getObject(); } @@ -437,9 +432,9 @@ boolean logical, Rule rule, Activation activation) throws FactException { + this.lock.lock(); + try { - synchronized ( this.ruleBase.getLock() ) { - // check if the object already exists in the WM FactHandleImpl handle = (FactHandleImpl) this.identityMap.get( object ); @@ -531,6 +526,8 @@ handle, object ); return handle; + } finally { + this.lock.unlock(); } } @@ -595,9 +592,9 @@ * The object. */ void putObject(FactHandle handle, - Object object) { -// Object oldValue = this.objects.put( ((FactHandleImpl) handle).getId(), -// object ); + Object object) { + // Object oldValue = this.objects.put( ((FactHandleImpl) handle).getId(), + // object ); this.identityMap.put( object, handle ); @@ -631,7 +628,8 @@ boolean updateEqualsMap, Rule rule, Activation activation) throws FactException { - synchronized ( this.ruleBase.getLock() ) { + this.lock.lock(); + try { removePropertyChangeListener( handle ); PropagationContext propagationContext = new PropagationContextImpl( this.propagationIdCounter++, @@ -668,6 +666,8 @@ oldObject ); ((FactHandleImpl) handle).invalidate(); + } finally { + this.lock.unlock(); } } @@ -686,7 +686,8 @@ Object object, Rule rule, Activation activation) throws FactException { - synchronized ( this.ruleBase.getLock() ) { + this.lock.lock(); + try { Object originalObject = removeObject( handle ); if ( originalObject == null ) { @@ -731,6 +732,8 @@ handle, originalObject, object ); + } finally { + this.lock.unlock(); } } @@ -857,6 +860,10 @@ this.ruleBase.disposeWorkingMemory( this ); } + public Lock getLock() { + return this.lock; + } + private static class FactStatus { private int counter; private String status; |