You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by sh...@apache.org on 2017/07/31 13:52:54 UTC
[1/2] lucene-solr:branch_7x: SOLR-6086: Replica is active during
autowarming resulting in queries being sent to a replica that may not have a
registered searcher. This causes spikes in response times when adding a
replica in busy clusters
Repository: lucene-solr
Updated Branches:
refs/heads/branch_7x 9d49a3a95 -> 98f900943
SOLR-6086: Replica is active during autowarming resulting in queries being sent to a replica that may not have a registered searcher. This causes spikes in response times when adding a replica in busy clusters
(cherry picked from commit 90da5ce)
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/7aeef02b
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/7aeef02b
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/7aeef02b
Branch: refs/heads/branch_7x
Commit: 7aeef02bdf515b33a93e0e3a460ac461b8f70165
Parents: 9d49a3a
Author: Shalin Shekhar Mangar <sh...@apache.org>
Authored: Sun Jul 30 20:20:20 2017 +0530
Committer: Shalin Shekhar Mangar <sh...@apache.org>
Committed: Mon Jul 31 19:22:12 2017 +0530
----------------------------------------------------------------------
solr/CHANGES.txt | 4 +
.../org/apache/solr/cloud/ZkController.java | 59 ++-
.../handler/component/RealTimeGetComponent.java | 8 +-
.../org/apache/solr/util/TestInjection.java | 36 ++
.../solr/cloud/TestCloudSearcherWarming.java | 360 +++++++++++++++++++
5 files changed, 464 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/7aeef02b/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 0c7b6c8..2232b55 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -60,6 +60,10 @@ Bug Fixes
* SOLR-10944: Get expression fails to return EOF tuple (Susheel Kumar, Joel Bernstein)
+* SOLR-6086: Replica is active during autowarming resulting in queries being sent to a replica that
+ may not have a registered searcher. This causes spikes in response times when adding a replica
+ in busy clusters. (Ludovic Boutros, Timothy Potter, shalin)
+
Optimizations
----------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/7aeef02b/solr/core/src/java/org/apache/solr/cloud/ZkController.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/cloud/ZkController.java b/solr/core/src/java/org/apache/solr/cloud/ZkController.java
index dee833f..a529e94 100644
--- a/solr/core/src/java/org/apache/solr/cloud/ZkController.java
+++ b/solr/core/src/java/org/apache/solr/cloud/ZkController.java
@@ -42,6 +42,7 @@ import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
@@ -93,8 +94,11 @@ import org.apache.solr.core.SolrCore;
import org.apache.solr.core.SolrCoreInitializationException;
import org.apache.solr.handler.admin.ConfigSetsHandlerApi;
import org.apache.solr.logging.MDCLoggingContext;
+import org.apache.solr.search.SolrIndexSearcher;
import org.apache.solr.servlet.SolrDispatchFilter;
import org.apache.solr.update.UpdateLog;
+import org.apache.solr.util.RTimer;
+import org.apache.solr.util.RefCounted;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.KeeperException.ConnectionLossException;
@@ -1299,8 +1303,11 @@ public class ZkController {
props.put(ZkStateReader.CORE_NODE_NAME_PROP, coreNodeName);
}
try (SolrCore core = cc.getCore(cd.getName())) {
+ if (core != null && state == Replica.State.ACTIVE) {
+ ensureRegisteredSearcher(core);
+ }
if (core != null && core.getDirectoryFactory().isSharedStorage()) {
- if (core != null && core.getDirectoryFactory().isSharedStorage()) {
+ if (core.getDirectoryFactory().isSharedStorage()) {
props.put("dataDir", core.getDataDir());
UpdateLog ulog = core.getUpdateHandler().getUpdateLog();
if (ulog != null) {
@@ -1312,7 +1319,7 @@ public class ZkController {
// The core had failed to initialize (in a previous request, not this one), hence nothing to do here.
log.info("The core '{}' had failed to initialize before.", cd.getName());
}
-
+
ZkNodeProps m = new ZkNodeProps(props);
if (updateLastState) {
@@ -2511,4 +2518,52 @@ public class ZkController {
log.warn("Could not publish node as down: " + e.getMessage());
}
}
+
+ /**
+ * Ensures that a searcher is registered for the given core and if not, waits until one is registered
+ */
+ private static void ensureRegisteredSearcher(SolrCore core) throws InterruptedException {
+ if (!core.getSolrConfig().useColdSearcher) {
+ RefCounted<SolrIndexSearcher> registeredSearcher = core.getRegisteredSearcher();
+ if (registeredSearcher != null) {
+ log.debug("Found a registered searcher: {} for core: {}", registeredSearcher.get(), core);
+ registeredSearcher.decref();
+ } else {
+ Future[] waitSearcher = new Future[1];
+ log.info("No registered searcher found for core: {}, waiting until a searcher is registered before publishing as active", core.getName());
+ final RTimer timer = new RTimer();
+ RefCounted<SolrIndexSearcher> searcher = null;
+ try {
+ searcher = core.getSearcher(false, true, waitSearcher, true);
+ boolean success = true;
+ if (waitSearcher[0] != null) {
+ log.debug("Waiting for first searcher of core {}, id: {} to be registered", core.getName(), core);
+ try {
+ waitSearcher[0].get();
+ } catch (ExecutionException e) {
+ log.warn("Wait for a searcher to be registered for core " + core.getName() + ",id: " + core + " failed due to: " + e, e);
+ success = false;
+ }
+ }
+ if (success) {
+ if (searcher == null) {
+ // should never happen
+ log.debug("Did not find a searcher even after the future callback for core: {}, id: {}!!!", core.getName(), core);
+ } else {
+ log.info("Found a registered searcher: {}, took: {} ms for core: {}, id: {}", searcher.get(), timer.getTime(), core.getName(), core);
+ }
+ }
+ } finally {
+ if (searcher != null) {
+ searcher.decref();
+ }
+ }
+ }
+ RefCounted<SolrIndexSearcher> newestSearcher = core.getNewestSearcher(false);
+ if (newestSearcher != null) {
+ log.debug("Found newest searcher: {} for core: {}, id: {}", newestSearcher.get(), core.getName(), core);
+ newestSearcher.decref();
+ }
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/7aeef02b/solr/core/src/java/org/apache/solr/handler/component/RealTimeGetComponent.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/component/RealTimeGetComponent.java b/solr/core/src/java/org/apache/solr/handler/component/RealTimeGetComponent.java
index 6d70435..85cb6f6 100644
--- a/solr/core/src/java/org/apache/solr/handler/component/RealTimeGetComponent.java
+++ b/solr/core/src/java/org/apache/solr/handler/component/RealTimeGetComponent.java
@@ -84,6 +84,7 @@ import org.apache.solr.update.IndexFingerprint;
import org.apache.solr.update.PeerSync;
import org.apache.solr.update.UpdateLog;
import org.apache.solr.util.RefCounted;
+import org.apache.solr.util.TestInjection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -955,10 +956,15 @@ public class RealTimeGetComponent extends SearchComponent
}
public void processGetFingeprint(ResponseBuilder rb) throws IOException {
+ TestInjection.injectFailIndexFingerprintRequests();
+
SolrQueryRequest req = rb.req;
SolrParams params = req.getParams();
-
+
long maxVersion = params.getLong("getFingerprint", Long.MAX_VALUE);
+ if (TestInjection.injectWrongIndexFingerprint()) {
+ maxVersion = -1;
+ }
IndexFingerprint fingerprint = IndexFingerprint.getFingerprint(req.getCore(), Math.abs(maxVersion));
rb.rsp.add("fingerprint", fingerprint);
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/7aeef02b/solr/core/src/java/org/apache/solr/util/TestInjection.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/util/TestInjection.java b/solr/core/src/java/org/apache/solr/util/TestInjection.java
index d7584da..422de73 100644
--- a/solr/core/src/java/org/apache/solr/util/TestInjection.java
+++ b/solr/core/src/java/org/apache/solr/util/TestInjection.java
@@ -135,6 +135,10 @@ public class TestInjection {
public static String splitFailureBeforeReplicaCreation = null;
public static String waitForReplicasInSync = "true:60";
+
+ public static String failIndexFingerprintRequests = null;
+
+ public static String wrongIndexFingerprint = null;
private static Set<Timer> timers = Collections.synchronizedSet(new HashSet<Timer>());
@@ -152,11 +156,43 @@ public class TestInjection {
prepRecoveryOpPauseForever = null;
countPrepRecoveryOpPauseForever = new AtomicInteger(0);
waitForReplicasInSync = "true:60";
+ failIndexFingerprintRequests = null;
+ wrongIndexFingerprint = null;
for (Timer timer : timers) {
timer.cancel();
}
}
+
+ public static boolean injectWrongIndexFingerprint() {
+ if (wrongIndexFingerprint != null) {
+ Random rand = random();
+ if (null == rand) return true;
+
+ Pair<Boolean,Integer> pair = parseValue(wrongIndexFingerprint);
+ boolean enabled = pair.first();
+ int chanceIn100 = pair.second();
+ if (enabled && rand.nextInt(100) >= (100 - chanceIn100)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean injectFailIndexFingerprintRequests() {
+ if (failIndexFingerprintRequests != null) {
+ Random rand = random();
+ if (null == rand) return true;
+
+ Pair<Boolean,Integer> pair = parseValue(failIndexFingerprintRequests);
+ boolean enabled = pair.first();
+ int chanceIn100 = pair.second();
+ if (enabled && rand.nextInt(100) >= (100 - chanceIn100)) {
+ throw new SolrException(ErrorCode.SERVER_ERROR, "Random test index fingerprint fail");
+ }
+ }
+ return true;
+ }
public static boolean injectRandomDelayInCoreCreation() {
if (randomDelayInCoreCreation != null) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/7aeef02b/solr/core/src/test/org/apache/solr/cloud/TestCloudSearcherWarming.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/TestCloudSearcherWarming.java b/solr/core/src/test/org/apache/solr/cloud/TestCloudSearcherWarming.java
new file mode 100644
index 0000000..c0cd5b8
--- /dev/null
+++ b/solr/core/src/test/org/apache/solr/cloud/TestCloudSearcherWarming.java
@@ -0,0 +1,360 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.solr.cloud;
+
+import java.io.IOException;
+import java.lang.invoke.MethodHandles;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.solr.client.solrj.SolrClient;
+import org.apache.solr.client.solrj.SolrQuery;
+import org.apache.solr.client.solrj.SolrRequest;
+import org.apache.solr.client.solrj.SolrResponse;
+import org.apache.solr.client.solrj.SolrServerException;
+import org.apache.solr.client.solrj.embedded.JettySolrRunner;
+import org.apache.solr.client.solrj.impl.CloudSolrClient;
+import org.apache.solr.client.solrj.request.CollectionAdminRequest;
+import org.apache.solr.client.solrj.response.QueryResponse;
+import org.apache.solr.client.solrj.response.SolrResponseBase;
+import org.apache.solr.common.SolrInputDocument;
+import org.apache.solr.common.cloud.CollectionStatePredicate;
+import org.apache.solr.common.cloud.CollectionStateWatcher;
+import org.apache.solr.common.cloud.DocCollection;
+import org.apache.solr.common.cloud.Replica;
+import org.apache.solr.common.params.SolrParams;
+import org.apache.solr.common.util.ContentStream;
+import org.apache.solr.common.util.ContentStreamBase;
+import org.apache.solr.common.util.NamedList;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.core.SolrEventListener;
+import org.apache.solr.search.SolrIndexSearcher;
+import org.apache.solr.servlet.SolrDispatchFilter;
+import org.apache.solr.util.LogLevel;
+import org.apache.solr.util.RefCounted;
+import org.apache.solr.util.TestInjection;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Tests related to SOLR-6086
+ */
+@LogLevel("org.apache.solr.cloud.overseer.*=DEBUG,org.apache.solr.cloud.Overseer=DEBUG,org.apache.solr.cloud.ZkController=DEBUG")
+public class TestCloudSearcherWarming extends SolrCloudTestCase {
+ public static final AtomicReference<String> coreNodeNameRef = new AtomicReference<>(null),
+ coreNameRef = new AtomicReference<>(null);
+ private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+ private static final AtomicInteger sleepTime = new AtomicInteger(-1);
+
+ @BeforeClass
+ public static void setupCluster() throws Exception {
+ useFactory("solr.StandardDirectoryFactory"); // necessary to find the index+tlog intact after restart
+ configureCluster(1)
+ .addConfig("conf", configset("cloud-minimal"))
+ .configure();
+ }
+
+ @Before
+ public void before() {
+ coreNameRef.set(null);
+ coreNodeNameRef.set(null);
+ sleepTime.set(-1);
+
+ try {
+ CollectionAdminRequest.deleteCollection("testRepFactor1LeaderStartup").process(cluster.getSolrClient());
+ } catch (Exception e) {
+ // ignore
+ }
+ try {
+ CollectionAdminRequest.deleteCollection("testPeersyncFailureReplicationSuccess").process(cluster.getSolrClient());
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+
+ @Test
+ public void testRepFactor1LeaderStartup() throws Exception {
+ CloudSolrClient solrClient = cluster.getSolrClient();
+
+ String collectionName = "testRepFactor1LeaderStartup";
+ CollectionAdminRequest.Create create = CollectionAdminRequest.createCollection(collectionName, 1, 1)
+ .setCreateNodeSet(cluster.getJettySolrRunner(0).getNodeName());
+ create.process(solrClient);
+
+ waitForState("The collection should have 1 shard and 1 replica", collectionName, clusterShape(1, 1));
+
+ solrClient.setDefaultCollection(collectionName);
+ solrClient.getZkStateReader().registerCore(collectionName);
+
+ String addListenerCommand = "{" +
+ "'add-listener' : {'name':'newSearcherListener','event':'newSearcher', 'class':'" + SleepingSolrEventListener.class.getName() + "'}" +
+ "'add-listener' : {'name':'firstSearcherListener','event':'firstSearcher', 'class':'" + SleepingSolrEventListener.class.getName() + "'}" +
+ "}";
+
+ ConfigRequest request = new ConfigRequest(SolrRequest.METHOD.POST, "/config", addListenerCommand);
+ solrClient.request(request);
+
+ solrClient.add(new SolrInputDocument("id", "1"));
+ solrClient.commit();
+
+ AtomicInteger expectedDocs = new AtomicInteger(1);
+ AtomicReference<String> failingCoreNodeName = new AtomicReference<>();
+ CollectionStateWatcher stateWatcher = createActiveReplicaSearcherWatcher(expectedDocs, failingCoreNodeName);
+
+ JettySolrRunner runner = cluster.getJettySolrRunner(0);
+ cluster.stopJettySolrRunner(0);
+ waitForState("", collectionName, clusterShape(1, 0));
+ // restart
+ sleepTime.set(10000);
+ cluster.startJettySolrRunner(runner);
+ cluster.getSolrClient().getZkStateReader().registerCollectionStateWatcher(collectionName, stateWatcher);
+ waitForState("", collectionName, clusterShape(1, 1));
+ assertNull("No replica should have been active without registering a searcher, found: " + failingCoreNodeName.get(), failingCoreNodeName.get());
+ cluster.getSolrClient().getZkStateReader().removeCollectionStateWatcher(collectionName, stateWatcher);
+ }
+
+ public void testPeersyncFailureReplicationSuccess() throws Exception {
+ CloudSolrClient solrClient = cluster.getSolrClient();
+
+ String collectionName = "testPeersyncFailureReplicationSuccess";
+ CollectionAdminRequest.Create create = CollectionAdminRequest.createCollection(collectionName, 1, 1)
+ .setCreateNodeSet(cluster.getJettySolrRunner(0).getNodeName());
+ create.process(solrClient);
+
+ waitForState("The collection should have 1 shard and 1 replica", collectionName, clusterShape(1, 1));
+
+ solrClient.setDefaultCollection(collectionName);
+ solrClient.getZkStateReader().registerCore(collectionName);
+
+ String addListenerCommand = "{" +
+ "'add-listener' : {'name':'newSearcherListener','event':'newSearcher', 'class':'" + SleepingSolrEventListener.class.getName() + "'}" +
+ "'add-listener' : {'name':'firstSearcherListener','event':'firstSearcher', 'class':'" + SleepingSolrEventListener.class.getName() + "'}" +
+ "}";
+
+ ConfigRequest request = new ConfigRequest(SolrRequest.METHOD.POST, "/config", addListenerCommand);
+ solrClient.request(request);
+
+ solrClient.add(new SolrInputDocument("id", "1"));
+ solrClient.commit();
+
+ AtomicInteger expectedDocs = new AtomicInteger(1);
+ AtomicReference<String> failingCoreNodeName = new AtomicReference<>();
+
+ QueryResponse response = solrClient.query(new SolrQuery("*:*"));
+ assertEquals(1, response.getResults().getNumFound());
+
+ // reset
+ coreNameRef.set(null);
+ coreNodeNameRef.set(null);
+ failingCoreNodeName.set(null);
+ sleepTime.set(5000);
+
+ CollectionStateWatcher stateWatcher = createActiveReplicaSearcherWatcher(expectedDocs, failingCoreNodeName);
+ cluster.getSolrClient().getZkStateReader().registerCollectionStateWatcher(collectionName, stateWatcher);
+
+ JettySolrRunner newNode = cluster.startJettySolrRunner();
+ CollectionAdminRequest.addReplicaToShard(collectionName, "shard1")
+ .setNode(newNode.getNodeName())
+ .process(solrClient);
+
+ waitForState("The collection should have 1 shard and 2 replica", collectionName, clusterShape(1, 2));
+ assertNull("No replica should have been active without registering a searcher, found: " + failingCoreNodeName.get(), failingCoreNodeName.get());
+
+ // stop the old node
+ log.info("Stopping old node 1");
+ AtomicReference<String> oldNodeName = new AtomicReference<>(cluster.getJettySolrRunner(0).getNodeName());
+ JettySolrRunner oldNode = cluster.stopJettySolrRunner(0);
+ // the newly created replica should become leader
+ waitForState("The collection should have 1 shard and 1 replica", collectionName, clusterShape(1, 1));
+ // the above call is not enough because we want to assert that the down'ed replica is not active
+ // but clusterShape will also return true if replica is not live -- which we don't want
+ CollectionStatePredicate collectionStatePredicate = (liveNodes, collectionState) -> {
+ for (Replica r : collectionState.getReplicas()) {
+ if (r.getNodeName().equals(oldNodeName.get())) {
+ return r.getState() == Replica.State.DOWN;
+ }
+ }
+ return false;
+ };
+ waitForState("", collectionName, collectionStatePredicate);
+ assertNotNull(solrClient.getZkStateReader().getLeaderRetry(collectionName, "shard1"));
+
+ // reset
+ coreNameRef.set(null);
+ coreNodeNameRef.set(null);
+ failingCoreNodeName.set(null);
+ sleepTime.set(5000);
+
+ // inject wrong signature output
+ TestInjection.wrongIndexFingerprint = "true:100";
+ // now lets restart the old node
+ log.info("Starting old node 1");
+ cluster.startJettySolrRunner(oldNode);
+ waitForState("", collectionName, clusterShape(1, 2));
+ // invoke statewatcher explicitly to avoid race condition where the assert happens before the state watcher is invoked by ZkStateReader
+ cluster.getSolrClient().getZkStateReader().registerCollectionStateWatcher(collectionName, stateWatcher);
+ assertNull("No replica should have been active without registering a searcher, found: " + failingCoreNodeName.get(), failingCoreNodeName.get());
+
+ oldNodeName.set(cluster.getJettySolrRunner(1).getNodeName());
+ assertSame(oldNode, cluster.stopJettySolrRunner(1)); // old node is now at 1
+ log.info("Stopping old node 2");
+ waitForState("", collectionName, clusterShape(1, 1));
+ waitForState("", collectionName, collectionStatePredicate);
+
+ // reset
+ coreNameRef.set(null);
+ coreNodeNameRef.set(null);
+ failingCoreNodeName.set(null);
+ sleepTime.set(14000); // has to be higher than the twice the recovery wait pause between attempts plus some margin
+
+ // inject failure
+ TestInjection.failIndexFingerprintRequests = "true:100";
+ // now lets restart the old node again
+ log.info("Starting old node 2");
+ cluster.startJettySolrRunner(oldNode);
+ waitForState("", collectionName, clusterShape(1, 2));
+ // invoke statewatcher explicitly to avoid race condition where the assert happens before the state watcher is invoked by ZkStateReader
+ cluster.getSolrClient().getZkStateReader().registerCollectionStateWatcher(collectionName, stateWatcher);
+ assertNull("No replica should have been active without registering a searcher, found: " + failingCoreNodeName.get(), failingCoreNodeName.get());
+ cluster.getSolrClient().getZkStateReader().removeCollectionStateWatcher(collectionName, stateWatcher);
+ }
+
+ private CollectionStateWatcher createActiveReplicaSearcherWatcher(AtomicInteger expectedDocs, AtomicReference<String> failingCoreNodeName) {
+ return new CollectionStateWatcher() {
+ @Override
+ public boolean onStateChanged(Set<String> liveNodes, DocCollection collectionState) {
+ try {
+ String coreNodeName = coreNodeNameRef.get();
+ String coreName = coreNameRef.get();
+ if (coreNodeName == null || coreName == null) return false;
+ Replica replica = collectionState.getReplica(coreNodeName);
+ if (replica == null) return false;
+ log.info("Collection state: {}", collectionState);
+ if (replica.isActive(liveNodes)) {
+ log.info("Active replica: {}", coreNodeName);
+ for (int i = 0; i < cluster.getJettySolrRunners().size(); i++) {
+ JettySolrRunner jettySolrRunner = cluster.getJettySolrRunner(i);
+ log.info("Checking node: {}", jettySolrRunner.getNodeName());
+ if (jettySolrRunner.getNodeName().equals(replica.getNodeName())) {
+ SolrDispatchFilter solrDispatchFilter = jettySolrRunner.getSolrDispatchFilter();
+ try (SolrCore core = solrDispatchFilter.getCores().getCore(coreName)) {
+ if (core.getSolrConfig().useColdSearcher) {
+ log.error("useColdSearcher is enabled! It should not be enabled for this test!");
+ assert false;
+ return false;
+ }
+ log.info("Found SolrCore: {}, id: {}", core.getName(), core);
+ RefCounted<SolrIndexSearcher> registeredSearcher = core.getRegisteredSearcher();
+ if (registeredSearcher != null) {
+ log.error("registered searcher not null, maxdocs = {}", registeredSearcher.get().maxDoc());
+ if (registeredSearcher.get().maxDoc() != expectedDocs.get()) {
+ failingCoreNodeName.set(coreNodeName);
+ registeredSearcher.decref();
+ return false;
+ } else {
+ registeredSearcher.decref();
+ return false;
+ }
+ } else {
+ log.error("registered searcher was null!");
+ RefCounted<SolrIndexSearcher> newestSearcher = core.getNewestSearcher(false);
+ if (newestSearcher != null) {
+ SolrIndexSearcher searcher = newestSearcher.get();
+ log.warn("newest searcher was: {}", searcher);
+ newestSearcher.decref();
+ } else {
+ log.error("newest searcher was also null!");
+ }
+ // no registered searcher but replica is active!
+ failingCoreNodeName.set(coreNodeName);
+ }
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ log.error("Unexpected exception in state watcher", e);
+ }
+ return false;
+ }
+ };
+ }
+
+ public static class SleepingSolrEventListener implements SolrEventListener {
+ @Override
+ public void init(NamedList args) {
+ new RuntimeException().printStackTrace();
+ System.out.println(args);
+ }
+
+ @Override
+ public void postCommit() {
+
+ }
+
+ @Override
+ public void postSoftCommit() {
+
+ }
+
+ @Override
+ public void newSearcher(SolrIndexSearcher newSearcher, SolrIndexSearcher currentSearcher) {
+ if (sleepTime.get() > 0) {
+ TestCloudSearcherWarming.coreNodeNameRef.set(newSearcher.getCore().getCoreDescriptor().getCloudDescriptor().getCoreNodeName());
+ TestCloudSearcherWarming.coreNameRef.set(newSearcher.getCore().getName());
+ log.info("Sleeping for {} on newSearcher: {}, currentSearcher: {} belonging to (newest) core: {}, id: {}", sleepTime.get(), newSearcher, currentSearcher, newSearcher.getCore().getName(), newSearcher.getCore());
+ try {
+ Thread.sleep(sleepTime.get());
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ log.info("Finished sleeping for {} on newSearcher: {}, currentSearcher: {} belonging to (newest) core: {}, id: {}", sleepTime.get(), newSearcher, currentSearcher, newSearcher.getCore().getName(), newSearcher.getCore());
+ }
+ }
+ }
+
+ public static class ConfigRequest extends SolrRequest {
+ protected final String message;
+
+ public ConfigRequest(METHOD m, String path, String message) {
+ super(m, path);
+ this.message = message;
+ }
+
+ @Override
+ public SolrParams getParams() {
+ return null;
+ }
+
+ @Override
+ public Collection<ContentStream> getContentStreams() throws IOException {
+ return message != null ? Collections.singletonList(new ContentStreamBase.StringStream(message)) : null;
+ }
+
+ @Override
+ protected SolrResponse createResponse(SolrClient client) {
+ return new SolrResponseBase();
+ }
+ }
+}
[2/2] lucene-solr:branch_7x: SOLR-6086: Remove unused import
Posted by sh...@apache.org.
SOLR-6086: Remove unused import
(cherry picked from commit b1a65c8)
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/98f90094
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/98f90094
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/98f90094
Branch: refs/heads/branch_7x
Commit: 98f90094305628198866a52d2bd9289002cbbe9c
Parents: 7aeef02
Author: Shalin Shekhar Mangar <sh...@apache.org>
Authored: Mon Jul 31 08:12:29 2017 +0530
Committer: Shalin Shekhar Mangar <sh...@apache.org>
Committed: Mon Jul 31 19:22:25 2017 +0530
----------------------------------------------------------------------
.../src/test/org/apache/solr/cloud/TestCloudSearcherWarming.java | 1 -
1 file changed, 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/98f90094/solr/core/src/test/org/apache/solr/cloud/TestCloudSearcherWarming.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/TestCloudSearcherWarming.java b/solr/core/src/test/org/apache/solr/cloud/TestCloudSearcherWarming.java
index c0cd5b8..761785d 100644
--- a/solr/core/src/test/org/apache/solr/cloud/TestCloudSearcherWarming.java
+++ b/solr/core/src/test/org/apache/solr/cloud/TestCloudSearcherWarming.java
@@ -29,7 +29,6 @@ import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrRequest;
import org.apache.solr.client.solrj.SolrResponse;
-import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.embedded.JettySolrRunner;
import org.apache.solr.client.solrj.impl.CloudSolrClient;
import org.apache.solr.client.solrj.request.CollectionAdminRequest;