You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by mk...@apache.org on 2016/12/22 05:38:59 UTC

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

Repository: lucene-solr
Updated Branches:
  refs/heads/master d5e87898b -> 393e36e1c


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


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/393e36e1
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/393e36e1
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/393e36e1

Branch: refs/heads/master
Commit: 393e36e1ce0144a412bc8ea78e98a897a0ac77dd
Parents: d5e8789
Author: Mikhail Khludnev <mk...@apache.org>
Authored: Thu Dec 22 08:17:20 2016 +0300
Committer: Mikhail Khludnev <mk...@apache.org>
Committed: Thu Dec 22 08:18:38 2016 +0300

----------------------------------------------------------------------
 solr/CHANGES.txt                                |  2 +
 .../solr/handler/admin/LukeRequestHandler.java  | 18 ++++-
 .../solr/handler/admin/StatsReloadRaceTest.java | 82 +++++++++++++-------
 3 files changed, 74 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/393e36e1/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index d17afce..b2ec5ef 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -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
 ----------------------
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/393e36e1/solr/core/src/java/org/apache/solr/handler/admin/LukeRequestHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/LukeRequestHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/LukeRequestHandler.java
index d0dd152..d7dedf1 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/LukeRequestHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/LukeRequestHandler.java
@@ -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);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/393e36e1/solr/core/src/test/org/apache/solr/handler/admin/StatsReloadRaceTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/handler/admin/StatsReloadRaceTest.java b/solr/core/src/test/org/apache/solr/handler/admin/StatsReloadRaceTest.java
index 619e7d5..7bf4939 100644
--- a/solr/core/src/test/org/apache/solr/handler/admin/StatsReloadRaceTest.java
+++ b/solr/core/src/test/org/apache/solr/handler/admin/StatsReloadRaceTest.java
@@ -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,35 +67,60 @@ 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());
+        isCompleted = checkReloadComlpetion(asyncId);
+      } while (!isCompleted);
+    }
+  }
 
-        assertFalse("expect status check w/o error, got:" + statusLog,
-                                  statusLog.contains(CoreAdminHandler.FAILED));
+  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());
 
-        isCompleted = statusLog.contains(CoreAdminHandler.COMPLETED);
-      } while (!isCompleted);
+  }
+
+  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); 
+      }
     }
   }