Author: doogie
Date: Thu Mar 11 18:59:34 2010 New Revision: 921990 URL: http://svn.apache.org/viewvc?rev=921990&view=rev Log: Fix bad caching. Previously, any call to getDelegator() would *always* walk the entire classpath, trying to find all implementations of DelegatorFactory. This was fixed by moving the cache higher up. In detail, the entity caching system only stored a String delegator name. It would then try to find the appropriate delegator to match that name. However, during a custom importer, the caching system was being exercised very heavily, so DelegatorFactory.getDelegator() was being called in a very tight loop. Since the delegator instances were not being cached at the high level, this caused a *big* slowdown; basically, a 15 minute importer was taking over 2 hours, and was no near finishing. This was because UtilObject.getObjectFromFactory would end up walking the entire classpath, finding every jar, looking at every zip entry, to try and find the appropriate file in META-INF/services. Modified: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/DelegatorFactory.java ofbiz/trunk/framework/entity/src/org/ofbiz/entity/DelegatorFactoryImpl.java ofbiz/trunk/framework/entity/src/org/ofbiz/entity/GenericDelegator.java Modified: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/DelegatorFactory.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/src/org/ofbiz/entity/DelegatorFactory.java?rev=921990&r1=921989&r2=921990&view=diff ============================================================================== --- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/DelegatorFactory.java (original) +++ ofbiz/trunk/framework/entity/src/org/ofbiz/entity/DelegatorFactory.java Thu Mar 11 18:59:34 2010 @@ -18,6 +18,8 @@ */ package org.ofbiz.entity; +import java.util.concurrent.ConcurrentHashMap; + import org.ofbiz.base.util.Debug; import org.ofbiz.base.util.Factory; import org.ofbiz.base.util.UtilObject; @@ -25,13 +27,29 @@ import org.ofbiz.base.util.UtilObject; /** <code>Delegator</code> factory abstract class. */ public abstract class DelegatorFactory implements Factory<Delegator, String> { public static final String module = DelegatorFactoryImpl.class.getName(); + private static final ConcurrentHashMap<String, Delegator> delegatorCache = new ConcurrentHashMap<String, Delegator>(); public static Delegator getDelegator(String delegatorName) { - try { - return UtilObject.getObjectFromFactory(DelegatorFactory.class, delegatorName); - } catch (ClassNotFoundException e) { - Debug.logError(e, module); + if (delegatorName == null) { + delegatorName = "default"; + //Debug.logWarning(new Exception("Location where getting delegator with null name"), "Got a getGenericDelegator call with a null delegatorName, assuming default for the name.", module); } - return null; + do { + Delegator delegator = delegatorCache.get(delegatorName); + + if (delegator != null) { + // setup the Entity ECA Handler + delegator.initEntityEcaHandler(); + //Debug.logInfo("got delegator(" + delegatorName + ") from cache", module); + return delegator; + } + try { + delegator = UtilObject.getObjectFromFactory(DelegatorFactory.class, delegatorName); + } catch (ClassNotFoundException e) { + Debug.logError(e, module); + } + //Debug.logInfo("putting delegator(" + delegatorName + ") into cache", module); + delegatorCache.putIfAbsent(delegatorName, delegator); + } while (true); } } Modified: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/DelegatorFactoryImpl.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/src/org/ofbiz/entity/DelegatorFactoryImpl.java?rev=921990&r1=921989&r2=921990&view=diff ============================================================================== --- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/DelegatorFactoryImpl.java (original) +++ ofbiz/trunk/framework/entity/src/org/ofbiz/entity/DelegatorFactoryImpl.java Thu Mar 11 18:59:34 2010 @@ -27,32 +27,13 @@ public class DelegatorFactoryImpl extend public static final String module = DelegatorFactoryImpl.class.getName(); public Delegator getInstance(String delegatorName) { - if (delegatorName == null) { - delegatorName = "default"; - Debug.logWarning(new Exception("Location where getting delegator with null name"), "Got a getGenericDelegator call with a null delegatorName, assuming default for the name.", module); + if (Debug.infoOn()) Debug.logInfo("Creating new delegator [" + delegatorName + "] (" + Thread.currentThread().getName() + ")", module); + //Debug.logInfo(new Exception(), "Showing stack where new delegator is being created...", module); + try { + return new GenericDelegator(delegatorName); + } catch (GenericEntityException e) { + Debug.logError(e, "Error creating delegator", module); + return null; } - GenericDelegator delegator = GenericDelegator.delegatorCache.get(delegatorName); - if (delegator == null) { - synchronized (GenericDelegator.delegatorCache) { - // must check if null again as one of the blocked threads can still enter - delegator = GenericDelegator.delegatorCache.get(delegatorName); - if (delegator == null) { - if (Debug.infoOn()) Debug.logInfo("Creating new delegator [" + delegatorName + "] (" + Thread.currentThread().getName() + ")", module); - //Debug.logInfo(new Exception(), "Showing stack where new delegator is being created...", module); - try { - delegator = new GenericDelegator(delegatorName); - } catch (GenericEntityException e) { - Debug.logError(e, "Error creating delegator", module); - } - if (delegator != null) { - GenericDelegator.delegatorCache.put(delegatorName, delegator); - } else { - Debug.logError("Could not create delegator with name " + delegatorName + ", constructor failed (got null value) not sure why/how.", module); - } - } - } - } - return delegator; } - } Modified: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/GenericDelegator.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/src/org/ofbiz/entity/GenericDelegator.java?rev=921990&r1=921989&r2=921990&view=diff ============================================================================== --- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/GenericDelegator.java (original) +++ ofbiz/trunk/framework/entity/src/org/ofbiz/entity/GenericDelegator.java Thu Mar 11 18:59:34 2010 @@ -95,9 +95,6 @@ public class GenericDelegator implements /** This flag is only here for lower level technical testing, it shouldn't be user configurable (or at least I don't think so yet); when true all operations without a transaction will be wrapped in one; seems to be necessary for some (all?) XA aware connection pools, and should improve overall stability and consistency */ public static final boolean alwaysUseTransaction = true; - /** the delegatorCache will now be a HashMap, allowing reload of definitions, - * but the delegator will always be the same object for the given name */ - public static Map<String, GenericDelegator> delegatorCache = FastMap.newInstance(); protected String delegatorName = null; protected DelegatorInfo delegatorInfo = null; @@ -274,8 +271,6 @@ public class GenericDelegator implements } // NOTE: doing some things before the ECAs and such to make sure it is in place just in case it is used in a service engine startup thing or something - // put the delegator in the master Map by its name - GenericDelegator.delegatorCache.put(delegatorName, this); // setup the crypto class this.crypto = new EntityCrypto(this); @@ -306,15 +301,15 @@ public class GenericDelegator implements } else { Debug.logInfo("Distributed Cache Clear System disabled for delegator [" + delegatorName + "]", module); } - - // setup the Entity ECA Handler - initEntityEcaHandler(); } /* (non-Javadoc) * @see org.ofbiz.entity.Delegator#initEntityEcaHandler() */ - public void initEntityEcaHandler() { + public synchronized void initEntityEcaHandler() { + if (!getDelegatorInfo().useEntityEca || this.entityEcaHandler != null) { + return; + } if (getDelegatorInfo().useEntityEca) { ClassLoader loader = Thread.currentThread().getContextClassLoader(); // initialize the entity eca handler |
Free forum by Nabble | Edit this page |