SOLR-4463: Fix SolrCoreState reference counting.

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1446716 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Mark Robert Miller 2013-02-15 18:32:31 +00:00
parent e0454efd7c
commit 2ab630b840
4 changed files with 80 additions and 40 deletions

View File

@ -123,6 +123,8 @@ Bug Fixes
* SOLR-4426: NRTCachingDirectoryFactory does not initialize maxCachedMB and maxMergeSizeMB
if <directoryFactory> is not present in solrconfig.xml (Jack Krupansky via shalin)
* SOLR-4463: Fix SolrCoreState reference counting. (Mark Miller)
Optimizations
----------------------

View File

@ -44,7 +44,6 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReentrantLock;
@ -150,7 +149,6 @@ public final class SolrCore implements SolrInfoMBean {
private final String dataDir;
private final UpdateHandler updateHandler;
private final SolrCoreState solrCoreState;
private int solrCoreStateRefCnt = 1;
private final long startTime;
private final RequestHandlers reqHandlers;
@ -396,7 +394,7 @@ public final class SolrCore implements SolrInfoMBean {
IndexSchema schema = new IndexSchema(config,
getSchema().getResourceName(), null);
increfSolrCoreState();
solrCoreState.increfSolrCoreState();
SolrCore core = new SolrCore(getName(), getDataDir(), config,
schema, coreDescriptor, updateHandler, prev);
@ -867,32 +865,6 @@ public final class SolrCore implements SolrInfoMBean {
public SolrCoreState getSolrCoreState() {
return solrCoreState;
}
private void increfSolrCoreState() {
synchronized (solrCoreState) {
if (solrCoreStateRefCnt == 0) {
throw new IllegalStateException("IndexWriter has been closed");
}
solrCoreStateRefCnt++;
}
}
private void decrefSolrCoreState(IndexWriterCloser closer) {
synchronized (solrCoreState) {
solrCoreStateRefCnt--;
if (solrCoreStateRefCnt == 0) {
try {
log.info("Closing SolrCoreState");
solrCoreState.close(closer);
} catch (Throwable t) {
log.error("Error closing SolrCoreState", t);
}
}
}
}
/**
* @return an update processor registered to the given name. Throw an exception if this chain is undefined
@ -976,10 +948,12 @@ public final class SolrCore implements SolrInfoMBean {
}
try {
if (updateHandler instanceof IndexWriterCloser) {
decrefSolrCoreState((IndexWriterCloser) updateHandler);
} else {
decrefSolrCoreState(null);
if (solrCoreState != null) {
if (updateHandler instanceof IndexWriterCloser) {
solrCoreState.decrefSolrCoreState((IndexWriterCloser) updateHandler);
} else {
solrCoreState.decrefSolrCoreState(null);
}
}
} catch (Throwable e) {
SolrException.log(log, e);
@ -1005,15 +979,14 @@ public final class SolrCore implements SolrInfoMBean {
}
if (solrCoreState != null) { // bad startup case
synchronized (solrCoreState) {
if (solrCoreStateRefCnt == 0) {
try {
directoryFactory.close();
} catch (Throwable t) {
SolrException.log(log, t);
}
if (solrCoreState.getSolrCoreStateRefCnt() == 0) {
try {
directoryFactory.close();
} catch (Throwable t) {
SolrException.log(log, t);
}
}
}

View File

@ -25,6 +25,8 @@ import org.apache.solr.core.CoreContainer;
import org.apache.solr.core.DirectoryFactory;
import org.apache.solr.core.SolrCore;
import org.apache.solr.util.RefCounted;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The state in this class can be easily shared between SolrCores across
@ -32,12 +34,46 @@ import org.apache.solr.util.RefCounted;
*
*/
public abstract class SolrCoreState {
public static Logger log = LoggerFactory.getLogger(SolrCoreState.class);
private final Object deleteLock = new Object();
public Object getUpdateLock() {
return deleteLock;
}
private int solrCoreStateRefCnt = 1;
public synchronized int getSolrCoreStateRefCnt() {
return solrCoreStateRefCnt;
}
public void increfSolrCoreState() {
synchronized (this) {
if (solrCoreStateRefCnt == 0) {
throw new IllegalStateException("IndexWriter has been closed");
}
solrCoreStateRefCnt++;
}
}
public void decrefSolrCoreState(IndexWriterCloser closer) {
synchronized (this) {
solrCoreStateRefCnt--;
if (solrCoreStateRefCnt == 0) {
try {
log.info("Closing SolrCoreState");
close(closer);
} catch (Throwable t) {
log.error("Error closing SolrCoreState", t);
}
}
}
}
public abstract Lock getCommitLock();
/**

View File

@ -22,6 +22,8 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathExpressionException;
@ -77,6 +79,33 @@ public class TestCoreContainer extends SolrTestCaseJ4 {
System.clearProperty("shareSchema");
}
}
@Test
public void testReload() throws Exception {
final CoreContainer cc = h.getCoreContainer();
class TestThread extends Thread {
@Override
public void run() {
cc.reload("collection1");
}
}
List<Thread> threads = new ArrayList<Thread>();
int numThreads = 4;
for (int i = 0; i < numThreads; i++) {
threads.add(new TestThread());
}
for (Thread thread : threads) {
thread.start();
}
for (Thread thread : threads) {
thread.join();
}
}
@Test
public void testPersist() throws Exception {