[jboss-svn-commits] JBL Code SVN: r13083 - in labs/jbossrules/trunk/drools-core/src/main/java/org/drools: reteoo and 1 other directory.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Wed Jul 4 12:38:01 EDT 2007


Author: mark.proctor at jboss.com
Date: 2007-07-04 12:38:01 -0400 (Wed, 04 Jul 2007)
New Revision: 13083

Modified:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractRuleBase.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooRuleBase.java
Log:
JBRULES-971 concurrent issue on Rete node's ObjectTypeConf buildCache

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractRuleBase.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractRuleBase.java	2007-07-04 16:15:47 UTC (rev 13082)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractRuleBase.java	2007-07-04 16:38:01 UTC (rev 13083)
@@ -73,7 +73,7 @@
     protected Map                                   pkgs;
 
     protected Map                                   processes;
-    
+
     protected Map                                   agendaGroupRuleTotals;
 
     protected transient CompositePackageClassLoader packageClassLoader;
@@ -98,7 +98,7 @@
     public AbstractRuleBase() {
 
     }
-    
+
     public synchronized int nextWorkingMemoryCounter() {
         return this.workingMemoryCounter++;
     }
@@ -120,7 +120,7 @@
         this.config = (config != null) ? config : new RuleBaseConfiguration();
         this.config.makeImmutable();
         this.factHandleFactory = factHandleFactory;
-        
+
         if ( this.config.isSequential() ) {
             this.agendaGroupRuleTotals = new HashMap();
         }
@@ -257,6 +257,7 @@
     public Map getAgendaGroupRuleTotals() {
         return this.agendaGroupRuleTotals;
     }
+
     /**
      * Add a <code>Package</code> to the network. Iterates through the
      * <code>Package</code> adding Each individual <code>Rule</code> to the
@@ -275,71 +276,74 @@
      */
     public synchronized void addPackage(final Package newPkg) throws PackageIntegrationException {
         newPkg.checkValidity();
-        final Package pkg = (Package) this.pkgs.get( newPkg.getName() );
-        // INVARIANT: lastAquiredLock always contains the index of the last aquired lock +1 
-        // in the working memory array 
-        int lastAquiredLock = 0;
-        // get a snapshot of current working memories for locking
-        final InternalWorkingMemory[] wms = getWorkingMemories();
 
-        try {
-            // Iterate each workingMemory and lock it
-            // This is so we don't update the Rete network during propagation
-            for ( lastAquiredLock = 0; lastAquiredLock < wms.length; lastAquiredLock++ ) {
-                wms[lastAquiredLock].getLock().lock();
-            }
+        synchronized ( this.pkgs ) {
+            final Package pkg = (Package) this.pkgs.get( newPkg.getName() );
+            // INVARIANT: lastAquiredLock always contains the index of the last aquired lock +1 
+            // in the working memory array 
+            int lastAquiredLock = 0;
+            // get a snapshot of current working memories for locking
+            final InternalWorkingMemory[] wms = getWorkingMemories();
 
-            if ( pkg != null ) {
-                mergePackage( pkg,
-                              newPkg );
-            } else {
-                this.pkgs.put( newPkg.getName(),
-                               newPkg );
-            }
+            try {
+                // Iterate each workingMemory and lock it
+                // This is so we don't update the Rete network during propagation
+                for ( lastAquiredLock = 0; lastAquiredLock < wms.length; lastAquiredLock++ ) {
+                    wms[lastAquiredLock].getLock().lock();
+                }
 
-            final Map newGlobals = newPkg.getGlobals();
+                if ( pkg != null ) {
+                    mergePackage( pkg,
+                                  newPkg );
+                } else {
+                    this.pkgs.put( newPkg.getName(),
+                                   newPkg );
+                }
 
-            // Check that the global data is valid, we cannot change the type
-            // of an already declared global variable
-            for ( final Iterator it = newGlobals.keySet().iterator(); it.hasNext(); ) {
-                final String identifier = (String) it.next();
-                final Class type = (Class) newGlobals.get( identifier );
-                final boolean f = this.globals.containsKey( identifier );
-                if ( f ) {
-                    final boolean y = !this.globals.get( identifier ).equals( type );
-                    if ( f && y ) {
-                        throw new PackageIntegrationException( pkg );
+                final Map newGlobals = newPkg.getGlobals();
+
+                // Check that the global data is valid, we cannot change the type
+                // of an already declared global variable
+                for ( final Iterator it = newGlobals.keySet().iterator(); it.hasNext(); ) {
+                    final String identifier = (String) it.next();
+                    final Class type = (Class) newGlobals.get( identifier );
+                    final boolean f = this.globals.containsKey( identifier );
+                    if ( f ) {
+                        final boolean y = !this.globals.get( identifier ).equals( type );
+                        if ( f && y ) {
+                            throw new PackageIntegrationException( pkg );
+                        }
                     }
                 }
-            }
-            this.globals.putAll( newGlobals );
+                this.globals.putAll( newGlobals );
 
-            final Rule[] rules = newPkg.getRules();
+                final Rule[] rules = newPkg.getRules();
 
-            for ( int i = 0; i < rules.length; ++i ) {
-                addRule( rules[i] );
-            }
+                for ( int i = 0; i < rules.length; ++i ) {
+                    addRule( rules[i] );
+                }
 
-            //and now the rule flows
-            if ( newPkg.getRuleFlows() != Collections.EMPTY_MAP ) {
-                Map flows = newPkg.getRuleFlows();
-                for ( Iterator iter = flows.entrySet().iterator(); iter.hasNext(); ) {
-                    Entry flow = (Entry) iter.next();
-                    this.processes.put( flow.getKey(),
-                                        flow.getValue() );
+                //and now the rule flows
+                if ( newPkg.getRuleFlows() != Collections.EMPTY_MAP ) {
+                    Map flows = newPkg.getRuleFlows();
+                    for ( Iterator iter = flows.entrySet().iterator(); iter.hasNext(); ) {
+                        Entry flow = (Entry) iter.next();
+                        this.processes.put( flow.getKey(),
+                                            flow.getValue() );
+                    }
                 }
-            }
 
-            this.packageClassLoader.addClassLoader( newPkg.getPackageCompilationData().getClassLoader() );
+                this.packageClassLoader.addClassLoader( newPkg.getPackageCompilationData().getClassLoader() );
 
-        } finally {
-            // Iterate each workingMemory and attempt to fire any rules, that were activated as a result 
-            // of the new rule addition. Unlock after fireAllRules();
+            } finally {
+                // Iterate each workingMemory and attempt to fire any rules, that were activated as a result 
+                // of the new rule addition. Unlock after fireAllRules();
 
-            // as per the INVARIANT defined above, we need to iterate from lastAquiredLock-1 to 0. 
-            for ( lastAquiredLock--; lastAquiredLock > -1; lastAquiredLock-- ) {
-                wms[lastAquiredLock].fireAllRules();
-                wms[lastAquiredLock].getLock().unlock();
+                // as per the INVARIANT defined above, we need to iterate from lastAquiredLock-1 to 0. 
+                for ( lastAquiredLock--; lastAquiredLock > -1; lastAquiredLock-- ) {
+                    wms[lastAquiredLock].fireAllRules();
+                    wms[lastAquiredLock].getLock().unlock();
+                }
             }
         }
 
@@ -402,88 +406,92 @@
     }
 
     public synchronized void removePackage(final String packageName) {
-        final Package pkg = (Package) this.pkgs.get( packageName );
+        synchronized ( this.pkgs ) {
+            final Package pkg = (Package) this.pkgs.get( packageName );
 
-        // INVARIANT: lastAquiredLock always contains the index of the last aquired lock +1 
-        // in the working memory array 
-        int lastAquiredLock = 0;
-        // get a snapshot of current working memories for locking
-        final InternalWorkingMemory[] wms = getWorkingMemories();
+            // INVARIANT: lastAquiredLock always contains the index of the last aquired lock +1 
+            // in the working memory array 
+            int lastAquiredLock = 0;
+            // get a snapshot of current working memories for locking
+            final InternalWorkingMemory[] wms = getWorkingMemories();
 
-        try {
-            // Iterate each workingMemory and lock it
-            // This is so we don't update the Rete network during propagation
-            for ( lastAquiredLock = 0; lastAquiredLock < wms.length; lastAquiredLock++ ) {
-                wms[lastAquiredLock].getLock().lock();
-            }
+            try {
+                // Iterate each workingMemory and lock it
+                // This is so we don't update the Rete network during propagation
+                for ( lastAquiredLock = 0; lastAquiredLock < wms.length; lastAquiredLock++ ) {
+                    wms[lastAquiredLock].getLock().lock();
+                }
 
-            final Rule[] rules = pkg.getRules();
+                final Rule[] rules = pkg.getRules();
 
-            for ( int i = 0; i < rules.length; ++i ) {
-                removeRule( rules[i] );
-            }
+                for ( int i = 0; i < rules.length; ++i ) {
+                    removeRule( rules[i] );
+                }
 
-            this.packageClassLoader.removeClassLoader( pkg.getPackageCompilationData().getClassLoader() );
+                this.packageClassLoader.removeClassLoader( pkg.getPackageCompilationData().getClassLoader() );
 
-            pkg.clear();
+                pkg.clear();
 
-            // getting the list of referenced globals 
-            final Set referencedGlobals = new HashSet();
-            for ( final Iterator it = this.pkgs.values().iterator(); it.hasNext(); ) {
-                final org.drools.rule.Package pkgref = (org.drools.rule.Package) it.next();
-                if ( pkgref != pkg ) {
-                    referencedGlobals.addAll( pkgref.getGlobals().keySet() );
+                // getting the list of referenced globals 
+                final Set referencedGlobals = new HashSet();
+                for ( final Iterator it = this.pkgs.values().iterator(); it.hasNext(); ) {
+                    final org.drools.rule.Package pkgref = (org.drools.rule.Package) it.next();
+                    if ( pkgref != pkg ) {
+                        referencedGlobals.addAll( pkgref.getGlobals().keySet() );
+                    }
                 }
-            }
-            // removing globals declared inside the package that are not shared
-            for ( final Iterator it = pkg.getGlobals().keySet().iterator(); it.hasNext(); ) {
-                final String globalName = (String) it.next();
-                if ( !referencedGlobals.contains( globalName ) ) {
-                    this.globals.remove( globalName );
+                // removing globals declared inside the package that are not shared
+                for ( final Iterator it = pkg.getGlobals().keySet().iterator(); it.hasNext(); ) {
+                    final String globalName = (String) it.next();
+                    if ( !referencedGlobals.contains( globalName ) ) {
+                        this.globals.remove( globalName );
+                    }
                 }
-            }
-            // removing the package itself from the list
-            this.pkgs.remove( pkg.getName() );
-        } finally {
-            // Iterate each workingMemory and attempt to fire any rules, that were activated as a result 
-            // of the new rule addition. Unlock after fireAllRules();
+                // removing the package itself from the list
+                this.pkgs.remove( pkg.getName() );
+            } finally {
+                // Iterate each workingMemory and attempt to fire any rules, that were activated as a result 
+                // of the new rule addition. Unlock after fireAllRules();
 
-            // as per the INVARIANT defined above, we need to iterate from lastAquiredLock-1 to 0. 
-            for ( lastAquiredLock--; lastAquiredLock > -1; lastAquiredLock-- ) {
-                wms[lastAquiredLock].fireAllRules();
-                wms[lastAquiredLock].getLock().unlock();
+                // as per the INVARIANT defined above, we need to iterate from lastAquiredLock-1 to 0. 
+                for ( lastAquiredLock--; lastAquiredLock > -1; lastAquiredLock-- ) {
+                    wms[lastAquiredLock].fireAllRules();
+                    wms[lastAquiredLock].getLock().unlock();
+                }
             }
         }
     }
 
-    public synchronized void removeRule(final String packageName,
-                                        final String ruleName) {
-        final Package pkg = (Package) this.pkgs.get( packageName );
-        final Rule rule = pkg.getRule( ruleName );
+    public void removeRule(final String packageName,
+                           final String ruleName) {
+        synchronized ( this.pkgs ) {
+            final Package pkg = (Package) this.pkgs.get( packageName );
+            final Rule rule = pkg.getRule( ruleName );
 
-        // INVARIANT: lastAquiredLock always contains the index of the last aquired lock +1 
-        // in the working memory array 
-        int lastAquiredLock = 0;
-        // get a snapshot of current working memories for locking
-        final InternalWorkingMemory[] wms = getWorkingMemories();
+            // INVARIANT: lastAquiredLock always contains the index of the last aquired lock +1 
+            // in the working memory array 
+            int lastAquiredLock = 0;
+            // get a snapshot of current working memories for locking
+            final InternalWorkingMemory[] wms = getWorkingMemories();
 
-        try {
-            // Iterate each workingMemory and lock it
-            // This is so we don't update the Rete network during propagation
-            for ( lastAquiredLock = 0; lastAquiredLock < wms.length; lastAquiredLock++ ) {
-                wms[lastAquiredLock].getLock().lock();
-            }
+            try {
+                // Iterate each workingMemory and lock it
+                // This is so we don't update the Rete network during propagation
+                for ( lastAquiredLock = 0; lastAquiredLock < wms.length; lastAquiredLock++ ) {
+                    wms[lastAquiredLock].getLock().lock();
+                }
 
-            removeRule( rule );
-            pkg.removeRule( rule );
+                removeRule( rule );
+                pkg.removeRule( rule );
 
-        } finally {
-            // Iterate each workingMemory and attempt to fire any rules, that were activated as a result 
-            // of the new rule addition. Unlock after fireAllRules();
+            } finally {
+                // Iterate each workingMemory and attempt to fire any rules, that were activated as a result 
+                // of the new rule addition. Unlock after fireAllRules();
 
-            // as per the INVARIANT defined above, we need to iterate from lastAquiredLock-1 to 0. 
-            for ( lastAquiredLock--; lastAquiredLock > -1; lastAquiredLock-- ) {
-                wms[lastAquiredLock].getLock().unlock();
+                // as per the INVARIANT defined above, we need to iterate from lastAquiredLock-1 to 0. 
+                for ( lastAquiredLock--; lastAquiredLock > -1; lastAquiredLock-- ) {
+                    wms[lastAquiredLock].getLock().unlock();
+                }
             }
         }
     }
@@ -511,7 +519,7 @@
         return (Package) this.pkgs.get( name );
     }
 
-    public StatefulSession[] getStatefulSessions() {        
+    public StatefulSession[] getStatefulSessions() {
         return (StatefulSession[]) this.statefulSessions.toArray( new StatefulSession[this.statefulSessions.size()] );
     }
 
@@ -534,14 +542,16 @@
                                                                           ClassNotFoundException {
 
         if ( this.config.isSequential() ) {
-            throw new RuntimeException( "Cannot have a stateful rule session, with sequential configuration set to true");
+            throw new RuntimeException( "Cannot have a stateful rule session, with sequential configuration set to true" );
         }
-        
+
         final DroolsObjectInputStream streamWithLoader = new DroolsObjectInputStream( stream,
                                                                                       this.packageClassLoader );
 
         final AbstractWorkingMemory workingMemory = (AbstractWorkingMemory) streamWithLoader.readObject();
-        workingMemory.setRuleBase( this );
+        synchronized ( this.pkgs ) {
+            workingMemory.setRuleBase( this );
+        }
 
         return (StatefulSession) workingMemory;
     }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooRuleBase.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooRuleBase.java	2007-07-04 16:15:47 UTC (rev 13082)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooRuleBase.java	2007-07-04 16:38:01 UTC (rev 13083)
@@ -126,7 +126,7 @@
         super( id,
                config,
                factHandleFactory );
-        this.rete = new Rete(this);
+        this.rete = new Rete( this );
         this.reteooBuilder = new ReteooBuilder( this );
     }
 
@@ -218,42 +218,45 @@
      */
     public synchronized StatefulSession newStatefulSession(final boolean keepReference) {
         if ( this.config.isSequential() ) {
-            throw new RuntimeException( "Cannot have a stateful rule session, with sequential configuration set to true");
+            throw new RuntimeException( "Cannot have a stateful rule session, with sequential configuration set to true" );
         }
+        ReteooStatefulSession session = null;
         
-        ExecutorService executor = this.config.getExecutorService();
-        final ReteooStatefulSession session = new ReteooStatefulSession( nextWorkingMemoryCounter(),
-                                                                         this,
-                                                                         executor );
-        
-        
-        executor.setCommandExecutor( new CommandExecutor( session ) );
+        synchronized ( this.pkgs ) {
+            ExecutorService executor = this.config.getExecutorService();
+            session = new ReteooStatefulSession( nextWorkingMemoryCounter(),
+                                                 this,
+                                                 executor );
 
-        if ( keepReference ) {
-            super.addStatefulSession( session );
-        }
+            executor.setCommandExecutor( new CommandExecutor( session ) );
 
-        final InitialFactHandle handle = new InitialFactHandle( session.getFactHandleFactory().newFactHandle( new InitialFactHandleDummyObject() ) );
+            if ( keepReference ) {
+                super.addStatefulSession( session );
+            }
 
-        session.queueWorkingMemoryAction( session.new WorkingMemoryReteAssertAction( handle,
-                                                                                     false,
-                                                                                     true,
-                                                                                     null,
-                                                                                     null ) );
+            final InitialFactHandle handle = new InitialFactHandle( session.getFactHandleFactory().newFactHandle( new InitialFactHandleDummyObject() ) );
 
+            session.queueWorkingMemoryAction( session.new WorkingMemoryReteAssertAction( handle,
+                                                                                         false,
+                                                                                         true,
+                                                                                         null,
+                                                                                         null ) );
+        }
         return session;
     }
-    
+
     public StatelessSession newStatelessSession() {
-        
+
         //orders the rules
         if ( this.config.isSequential() ) {
             this.reteooBuilder.order();
-        }                             
-        
-        return new ReteooStatelessSession( this );
-    }    
+        }
 
+        synchronized ( this.pkgs ) {
+            return new ReteooStatelessSession( this );
+        }
+    }
+
     protected synchronized void addRule(final Rule rule) throws InvalidPatternException {
         super.addRule( rule );
 




More information about the jboss-svn-commits mailing list