mirror of https://github.com/apache/lucene.git
LUCENE-3476: SearcherManager misses to close IR if manager is closed during reopen
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1177940 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
b4ff06f88e
commit
d514a4ac75
|
@ -152,7 +152,15 @@ public class SearcherManager implements Closeable {
|
|||
}
|
||||
}
|
||||
}
|
||||
swapSearcher(newSearcher);
|
||||
boolean success = false;
|
||||
try {
|
||||
swapSearcher(newSearcher);
|
||||
success = true;
|
||||
} finally {
|
||||
if (!success) {
|
||||
release(newSearcher);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -204,7 +212,12 @@ public class SearcherManager implements Closeable {
|
|||
* affected, and they should still call {@link #release}
|
||||
* after they are done. */
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
swapSearcher(null);
|
||||
public synchronized void close() throws IOException {
|
||||
if (currentSearcher != null) {
|
||||
// make sure we can call this more than once
|
||||
// closeable javadoc says:
|
||||
// if this is already closed then invoking this method has no effect.
|
||||
swapSearcher(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,10 +18,17 @@ package org.apache.lucene.search;
|
|||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.apache.lucene.analysis.MockAnalyzer;
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.index.IndexWriter;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.index.ThreadedIndexingAndSearchingTestCase;
|
||||
import org.apache.lucene.store.AlreadyClosedException;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.util._TestUtil;
|
||||
|
||||
public class TestSearcherManager extends ThreadedIndexingAndSearchingTestCase {
|
||||
|
@ -110,4 +117,74 @@ public class TestSearcherManager extends ThreadedIndexingAndSearchingTestCase {
|
|||
}
|
||||
mgr.close();
|
||||
}
|
||||
|
||||
public void testIntermediateClose() throws IOException, InterruptedException {
|
||||
Directory dir = newDirectory();
|
||||
IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(
|
||||
TEST_VERSION_CURRENT, new MockAnalyzer(random)));
|
||||
writer.addDocument(new Document());
|
||||
writer.commit();
|
||||
final CountDownLatch awaitEnterWarm = new CountDownLatch(1);
|
||||
final CountDownLatch awaitClose = new CountDownLatch(1);
|
||||
|
||||
final SearcherManager searcherManager = new SearcherManager(dir,
|
||||
new SearcherWarmer() {
|
||||
@Override
|
||||
public void warm(IndexSearcher s) throws IOException {
|
||||
try {
|
||||
awaitEnterWarm.countDown();
|
||||
awaitClose.await();
|
||||
} catch (InterruptedException e) {
|
||||
//
|
||||
}
|
||||
}
|
||||
});
|
||||
IndexSearcher searcher = searcherManager.acquire();
|
||||
try {
|
||||
assertEquals(1, searcher.getIndexReader().numDocs());
|
||||
} finally {
|
||||
searcherManager.release(searcher);
|
||||
}
|
||||
writer.addDocument(new Document());
|
||||
writer.commit();
|
||||
final AtomicBoolean success = new AtomicBoolean(false);
|
||||
final AtomicBoolean triedReopen = new AtomicBoolean(false);
|
||||
final Throwable[] exc = new Throwable[1];
|
||||
Thread thread = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
triedReopen.set(true);
|
||||
searcherManager.maybeReopen();
|
||||
success.set(true);
|
||||
} catch (AlreadyClosedException e) {
|
||||
// expected
|
||||
} catch (Throwable e) {
|
||||
exc[0] = e;
|
||||
// use success as the barrier here to make sure we see the write
|
||||
success.set(false);
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
thread.start();
|
||||
awaitEnterWarm.await();
|
||||
for (int i = 0; i < 2; i++) {
|
||||
searcherManager.close();
|
||||
}
|
||||
awaitClose.countDown();
|
||||
thread.join();
|
||||
try {
|
||||
searcherManager.acquire();
|
||||
fail("already closed");
|
||||
} catch (AlreadyClosedException ex) {
|
||||
// expected
|
||||
}
|
||||
assertFalse(success.get());
|
||||
assertTrue(triedReopen.get());
|
||||
assertNull("" + exc[0], exc[0]);
|
||||
writer.close();
|
||||
dir.close();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue