SOLR-9699: fixing exception on core status during concurrent reload

This commit is contained in:
Mikhail Khludnev 2016-12-22 08:17:20 +03:00
parent d5e87898b1
commit 393e36e1ce
3 changed files with 75 additions and 29 deletions

View File

@ -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
----------------------

View File

@ -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);

View File

@ -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);
}
}
}
}