You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by er...@apache.org on 2013/01/16 02:16:51 UTC
svn commit: r1433787 - in /lucene/dev/branches/lucene_solr_4_1: ./
dev-tools/ lucene/ lucene/analysis/
lucene/analysis/icu/src/java/org/apache/lucene/collation/ lucene/backwards/
lucene/benchmark/ lucene/codecs/ lucene/core/ lucene/core/src/test/org/ap...
Author: erick
Date: Wed Jan 16 01:16:50 2013
New Revision: 1433787
URL: http://svn.apache.org/viewvc?rev=1433787&view=rev
Log:
Fix for SOLR-4300, race condition when more than one thread loaded a lazy core
Modified:
lucene/dev/branches/lucene_solr_4_1/ (props changed)
lucene/dev/branches/lucene_solr_4_1/dev-tools/ (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/ (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/BUILD.txt (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/CHANGES.txt (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/JRE_VERSION_MIGRATION.txt (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/LICENSE.txt (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/MIGRATE.txt (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/NOTICE.txt (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/README.txt (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/SYSTEM_REQUIREMENTS.txt (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/analysis/ (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/analysis/icu/src/java/org/apache/lucene/collation/ICUCollationKeyFilterFactory.java (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/backwards/ (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/benchmark/ (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/build.xml (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/codecs/ (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/common-build.xml (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/core/ (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/core/src/test/org/apache/lucene/index/TestBackwardsCompatibility.java (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/core/src/test/org/apache/lucene/index/index.40.cfs.zip (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/core/src/test/org/apache/lucene/index/index.40.nocfs.zip (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/core/src/test/org/apache/lucene/index/index.40.optimized.cfs.zip (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/core/src/test/org/apache/lucene/index/index.40.optimized.nocfs.zip (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/demo/ (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/facet/ (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/grouping/ (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/highlighter/ (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/ivy-settings.xml (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/join/ (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/licenses/ (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/memory/ (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/misc/ (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/module-build.xml (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/queries/ (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/queryparser/ (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/sandbox/ (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/site/ (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/spatial/ (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/suggest/ (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/test-framework/ (props changed)
lucene/dev/branches/lucene_solr_4_1/lucene/tools/ (props changed)
lucene/dev/branches/lucene_solr_4_1/solr/ (props changed)
lucene/dev/branches/lucene_solr_4_1/solr/CHANGES.txt (props changed)
lucene/dev/branches/lucene_solr_4_1/solr/LICENSE.txt (props changed)
lucene/dev/branches/lucene_solr_4_1/solr/NOTICE.txt (props changed)
lucene/dev/branches/lucene_solr_4_1/solr/README.txt (props changed)
lucene/dev/branches/lucene_solr_4_1/solr/SYSTEM_REQUIREMENTS.txt (props changed)
lucene/dev/branches/lucene_solr_4_1/solr/build.xml (props changed)
lucene/dev/branches/lucene_solr_4_1/solr/cloud-dev/ (props changed)
lucene/dev/branches/lucene_solr_4_1/solr/common-build.xml (props changed)
lucene/dev/branches/lucene_solr_4_1/solr/contrib/ (props changed)
lucene/dev/branches/lucene_solr_4_1/solr/core/ (props changed)
lucene/dev/branches/lucene_solr_4_1/solr/core/src/java/org/apache/solr/core/CoreContainer.java
lucene/dev/branches/lucene_solr_4_1/solr/core/src/test/org/apache/solr/core/TestLazyCores.java
lucene/dev/branches/lucene_solr_4_1/solr/example/ (props changed)
lucene/dev/branches/lucene_solr_4_1/solr/licenses/ (props changed)
lucene/dev/branches/lucene_solr_4_1/solr/licenses/httpclient-LICENSE-ASL.txt (props changed)
lucene/dev/branches/lucene_solr_4_1/solr/licenses/httpclient-NOTICE.txt (props changed)
lucene/dev/branches/lucene_solr_4_1/solr/licenses/httpcore-LICENSE-ASL.txt (props changed)
lucene/dev/branches/lucene_solr_4_1/solr/licenses/httpcore-NOTICE.txt (props changed)
lucene/dev/branches/lucene_solr_4_1/solr/licenses/httpmime-LICENSE-ASL.txt (props changed)
lucene/dev/branches/lucene_solr_4_1/solr/licenses/httpmime-NOTICE.txt (props changed)
lucene/dev/branches/lucene_solr_4_1/solr/scripts/ (props changed)
lucene/dev/branches/lucene_solr_4_1/solr/site/ (props changed)
lucene/dev/branches/lucene_solr_4_1/solr/solrj/ (props changed)
lucene/dev/branches/lucene_solr_4_1/solr/test-framework/ (props changed)
lucene/dev/branches/lucene_solr_4_1/solr/testlogging.properties (props changed)
lucene/dev/branches/lucene_solr_4_1/solr/webapp/ (props changed)
Modified: lucene/dev/branches/lucene_solr_4_1/solr/core/src/java/org/apache/solr/core/CoreContainer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_4_1/solr/core/src/java/org/apache/solr/core/CoreContainer.java?rev=1433787&r1=1433786&r2=1433787&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_4_1/solr/core/src/java/org/apache/solr/core/CoreContainer.java (original)
+++ lucene/dev/branches/lucene_solr_4_1/solr/core/src/java/org/apache/solr/core/CoreContainer.java Wed Jan 16 01:16:50 2013
@@ -128,6 +128,8 @@ public class CoreContainer
protected final Map<String, CoreDescriptor> dynamicDescriptors = new LinkedHashMap<String, CoreDescriptor>();
+ protected final Set<String> pendingDynamicCoreLoads = new HashSet<String>();
+
protected final Map<String,Exception> coreInitFailures =
Collections.synchronizedMap(new LinkedHashMap<String,Exception>());
@@ -1245,17 +1247,8 @@ public class CoreContainer
}
}
}
-
- /** Gets a core by name and increase its refcount.
- * @see SolrCore#close()
- * @param name the core name
- * @return the core if found
- */
- public SolrCore getCore(String name) {
- name = checkDefault(name);
- // Do this in two phases since we don't want to lock access to the cores over a load.
+ private SolrCore getCoreFromAnyList(String name) {
SolrCore core;
-
synchronized (cores) {
core = cores.get(name);
if (core != null) {
@@ -1274,20 +1267,64 @@ public class CoreContainer
return core;
}
}
+ return null;
+ }
+ /** Gets a core by name and increase its refcount.
+ * @see SolrCore#close()
+ * @param name the core name
+ * @return the core if found
+ */
+ public SolrCore getCore(String name) {
+ name = checkDefault(name);
+ // Do this in two phases since we don't want to lock access to the cores over a load.
+ SolrCore core = getCoreFromAnyList(name);
+
+ if (core != null) return core;
+
+ // OK, it's not presently in any list, is it in the list of dynamic cores but not loaded yet? If so, load it.
CoreDescriptor desc = dynamicDescriptors.get(name);
if (desc == null) { //Nope, no transient core with this name
return null;
}
+
+ // Keep multiple threads from loading the same core at the same time.
try {
- core = create(desc); // This should throw an error if it fails.
- core.open();
- if (desc.isTransient()) {
- registerLazyCore(name, core, false); // This is a transient core
- } else {
- register(name, core, false); // This is a "permanent", although deferred-load core
+ boolean isPending;
+ synchronized (pendingDynamicCoreLoads) {
+ isPending = pendingDynamicCoreLoads.contains(name);
+ if (! isPending) {
+ pendingDynamicCoreLoads.add(name);
+ }
}
- } catch (Exception ex) {
- throw recordAndThrow(name, "Unable to create core" + name, ex);
+
+ while (isPending) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ return null; // Seems best not to do anything at all if the thread is interrupted
+ }
+
+ synchronized (pendingDynamicCoreLoads) {
+ if (!pendingDynamicCoreLoads.contains(name)) {
+ // NOTE: If, for some reason, the load failed, we'll return null here and presumably the log will show
+ // why. We'll fail all over again next time if the problem isn't corrected.
+ return getCoreFromAnyList(name);
+ }
+ }
+ }
+ try {
+ core = create(desc); // This should throw an error if it fails.
+ core.open();
+ if (desc.isTransient()) {
+ registerLazyCore(name, core, false); // This is a transient core
+ } else {
+ register(name, core, false); // This is a "permanent", although deferred-load core
+ }
+ } catch (Exception ex) {
+ throw recordAndThrow(name, "Unable to create core" + name, ex);
+ }
+ } finally {
+ pendingDynamicCoreLoads.remove(name);
}
return core;
}
Modified: lucene/dev/branches/lucene_solr_4_1/solr/core/src/test/org/apache/solr/core/TestLazyCores.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_4_1/solr/core/src/test/org/apache/solr/core/TestLazyCores.java?rev=1433787&r1=1433786&r2=1433787&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_4_1/solr/core/src/test/org/apache/solr/core/TestLazyCores.java (original)
+++ lucene/dev/branches/lucene_solr_4_1/solr/core/src/test/org/apache/solr/core/TestLazyCores.java Wed Jan 16 01:16:50 2013
@@ -34,8 +34,10 @@ import org.junit.Test;
import java.io.File;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.List;
public class TestLazyCores extends SolrTestCaseJ4 {
@@ -246,6 +248,44 @@ public class TestLazyCores extends SolrT
}
}
+ static List<SolrCore> _theCores = new ArrayList<SolrCore>();
+ // Test case for SOLR-4300
+ @Test
+ public void testRace() throws Exception {
+ final CoreContainer cc = init();
+ try {
+
+ Thread[] threads = new Thread[15];
+ for (int idx = 0; idx < threads.length; idx++) {
+ threads[idx] = new Thread() {
+ @Override
+ public void run() {
+ SolrCore core = cc.getCore("collectionLazy3");
+ synchronized (_theCores) {
+ _theCores.add(core);
+ }
+ }
+ };
+ threads[idx].start();
+ }
+
+ for (Thread thread : threads) {
+ thread.join();
+ }
+
+ for (int idx = 0; idx < _theCores.size() - 1; ++idx) {
+ assertEquals("Cores should be the same!", _theCores.get(idx), _theCores.get(idx + 1));
+ }
+
+ for (SolrCore core : _theCores) {
+ core.close();
+ }
+
+ } finally {
+ cc.shutdown();
+ }
+ }
+
private void checkNotInCores(CoreContainer cc, String... nameCheck) {
Collection<String> names = cc.getCoreNames();
for (String name : nameCheck) {