mirror of https://github.com/apache/lucene.git
SOLR-9699: fixing exception on core status during concurrent reload
This commit is contained in:
parent
d5e87898b1
commit
393e36e1ce
|
@ -279,6 +279,8 @@ Bug Fixes
|
|||
|
||||
* SOLR-9760: Windows script doesn't need write permission (Alex Crome by Mikhail Khludnev)
|
||||
|
||||
* SOLR-9699,SOLR-4668: fix exception from core status in parallel with core reload (Mikhail Khludnev)
|
||||
|
||||
Other Changes
|
||||
----------------------
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@ import org.apache.lucene.index.Terms;
|
|||
import org.apache.lucene.index.TermsEnum;
|
||||
import org.apache.lucene.search.DocIdSetIterator;
|
||||
import org.apache.lucene.search.similarities.Similarity;
|
||||
import org.apache.lucene.store.AlreadyClosedException;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.util.Bits;
|
||||
import org.apache.lucene.util.BytesRef;
|
||||
|
@ -577,7 +578,7 @@ public class LukeRequestHandler extends RequestHandlerBase
|
|||
|
||||
indexInfo.add("version", reader.getVersion()); // TODO? Is this different then: IndexReader.getCurrentVersion( dir )?
|
||||
indexInfo.add("segmentCount", reader.leaves().size());
|
||||
indexInfo.add("current", reader.isCurrent() );
|
||||
indexInfo.add("current", closeSafe( reader::isCurrent));
|
||||
indexInfo.add("hasDeletions", reader.hasDeletions() );
|
||||
indexInfo.add("directory", dir );
|
||||
IndexCommit indexCommit = reader.getIndexCommit();
|
||||
|
@ -593,6 +594,21 @@ public class LukeRequestHandler extends RequestHandlerBase
|
|||
return indexInfo;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface IOSupplier {
|
||||
boolean get() throws IOException;
|
||||
}
|
||||
|
||||
private static Object closeSafe(IOSupplier isCurrent) {
|
||||
try {
|
||||
return isCurrent.get();
|
||||
}catch(AlreadyClosedException | IOException exception) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static long getFileLength(Directory dir, String filename) {
|
||||
try {
|
||||
return dir.fileLength(filename);
|
||||
|
|
|
@ -18,6 +18,7 @@ package org.apache.solr.handler.admin;
|
|||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.apache.solr.SolrTestCaseJ4;
|
||||
|
@ -50,11 +51,13 @@ public class StatsReloadRaceTest extends SolrTestCaseJ4 {
|
|||
@Test
|
||||
public void testParallelReloadAndStats() throws Exception {
|
||||
|
||||
for (int i = 0; i < atLeast(2); i++) {
|
||||
Random random = random();
|
||||
|
||||
for (int i = 0; i < atLeast(random, 2); i++) {
|
||||
|
||||
int asyncId = taskNum.incrementAndGet();
|
||||
|
||||
SolrQueryResponse rsp = new SolrQueryResponse();
|
||||
|
||||
h.getCoreContainer().getMultiCoreHandler().handleRequest(req(
|
||||
CommonParams.QT, "/admin/cores",
|
||||
CoreAdminParams.ACTION,
|
||||
|
@ -64,36 +67,61 @@ public class StatsReloadRaceTest extends SolrTestCaseJ4 {
|
|||
|
||||
boolean isCompleted;
|
||||
do {
|
||||
String stats = h.query(req(
|
||||
CommonParams.QT, "/admin/mbeans",
|
||||
"stats", "true"));
|
||||
|
||||
NamedList<NamedList<Object>> actualStats = SolrInfoMBeanHandler.fromXML(stats).get("CORE");
|
||||
|
||||
for (Map.Entry<String, NamedList<Object>> tuple : actualStats) {
|
||||
if (tuple.getKey().contains("earcher")) { // catches "searcher" and "Searcher@345345 blah"
|
||||
NamedList<Object> searcherStats = tuple.getValue();
|
||||
@SuppressWarnings("unchecked")
|
||||
NamedList<Object> statsList = (NamedList<Object>)searcherStats.get("stats");
|
||||
assertEquals("expect to have exactly one indexVersion at "+statsList, 1, statsList.getAll("indexVersion").size());
|
||||
assertTrue(statsList.get("indexVersion") instanceof Long);
|
||||
}
|
||||
if (random.nextBoolean()) {
|
||||
requestMbeans();
|
||||
} else {
|
||||
requestCoreStatus();
|
||||
}
|
||||
|
||||
h.getCoreContainer().getMultiCoreHandler().handleRequest(req(
|
||||
CoreAdminParams.ACTION,
|
||||
CoreAdminParams.CoreAdminAction.REQUESTSTATUS.toString(),
|
||||
CoreAdminParams.REQUESTID, "" + asyncId), rsp);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Object> statusLog = rsp.getValues().getAll(CoreAdminAction.STATUS.name());
|
||||
|
||||
assertFalse("expect status check w/o error, got:" + statusLog,
|
||||
statusLog.contains(CoreAdminHandler.FAILED));
|
||||
|
||||
isCompleted = statusLog.contains(CoreAdminHandler.COMPLETED);
|
||||
isCompleted = checkReloadComlpetion(asyncId);
|
||||
} while (!isCompleted);
|
||||
}
|
||||
}
|
||||
|
||||
private void requestCoreStatus() throws Exception {
|
||||
SolrQueryResponse rsp = new SolrQueryResponse();
|
||||
h.getCoreContainer().getMultiCoreHandler().handleRequest(req(
|
||||
CoreAdminParams.ACTION,
|
||||
CoreAdminParams.CoreAdminAction.STATUS.toString(),
|
||||
"core", DEFAULT_TEST_CORENAME), rsp);
|
||||
assertNull(""+rsp.getException(),rsp.getException());
|
||||
|
||||
}
|
||||
|
||||
private boolean checkReloadComlpetion(int asyncId) {
|
||||
boolean isCompleted;
|
||||
SolrQueryResponse rsp = new SolrQueryResponse();
|
||||
h.getCoreContainer().getMultiCoreHandler().handleRequest(req(
|
||||
CoreAdminParams.ACTION,
|
||||
CoreAdminParams.CoreAdminAction.REQUESTSTATUS.toString(),
|
||||
CoreAdminParams.REQUESTID, "" + asyncId), rsp);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Object> statusLog = rsp.getValues().getAll(CoreAdminAction.STATUS.name());
|
||||
|
||||
assertFalse("expect status check w/o error, got:" + statusLog,
|
||||
statusLog.contains(CoreAdminHandler.FAILED));
|
||||
|
||||
isCompleted = statusLog.contains(CoreAdminHandler.COMPLETED);
|
||||
return isCompleted;
|
||||
}
|
||||
|
||||
private void requestMbeans() throws Exception {
|
||||
String stats = h.query(req(
|
||||
CommonParams.QT, "/admin/mbeans",
|
||||
"stats", "true"));
|
||||
|
||||
NamedList<NamedList<Object>> actualStats = SolrInfoMBeanHandler.fromXML(stats).get("CORE");
|
||||
|
||||
for (Map.Entry<String, NamedList<Object>> tuple : actualStats) {
|
||||
if (tuple.getKey().contains("earcher")) { // catches "searcher" and "Searcher@345345 blah"
|
||||
NamedList<Object> searcherStats = tuple.getValue();
|
||||
@SuppressWarnings("unchecked")
|
||||
NamedList<Object> statsList = (NamedList<Object>)searcherStats.get("stats");
|
||||
assertEquals("expect to have exactly one indexVersion at "+statsList, 1, statsList.getAll("indexVersion").size());
|
||||
assertTrue(statsList.get("indexVersion") instanceof Long);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue