You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@solr.apache.org by no...@apache.org on 2023/07/05 08:38:30 UTC
[solr] branch main updated: SOLR-16860: Remove watch from ZkStateReader of Coordinator Node when collection is deleted (#1752)
This is an automated email from the ASF dual-hosted git repository.
noble pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr.git
The following commit(s) were added to refs/heads/main by this push:
new 1bdaf44676c SOLR-16860: Remove watch from ZkStateReader of Coordinator Node when collection is deleted (#1752)
1bdaf44676c is described below
commit 1bdaf44676c29931b1749e8275732c6987fccd4f
Author: patsonluk <pa...@users.noreply.github.com>
AuthorDate: Wed Jul 5 01:38:25 2023 -0700
SOLR-16860: Remove watch from ZkStateReader of Coordinator Node when collection is deleted (#1752)
---
.../solr/servlet/CoordinatorHttpSolrCall.java | 8 +++-
.../solr/common/cloud/ZkStateReaderAccessor.java | 5 +++
.../apache/solr/search/TestCoordinatorRole.java | 52 ++++++++++++++++++++++
.../apache/solr/common/cloud/ZkStateReader.java | 5 +++
4 files changed, 69 insertions(+), 1 deletion(-)
diff --git a/solr/core/src/java/org/apache/solr/servlet/CoordinatorHttpSolrCall.java b/solr/core/src/java/org/apache/solr/servlet/CoordinatorHttpSolrCall.java
index 44f1fd5f837..a9448d1310c 100644
--- a/solr/core/src/java/org/apache/solr/servlet/CoordinatorHttpSolrCall.java
+++ b/solr/core/src/java/org/apache/solr/servlet/CoordinatorHttpSolrCall.java
@@ -96,7 +96,13 @@ public class CoordinatorHttpSolrCall extends HttpSolrCall {
SolrCore core = solrCall.getCoreByCollection(syntheticCollectionName, isPreferLeader);
if (core != null) {
factory.collectionVsCoreNameMapping.put(collectionName, core.getName());
- solrCall.cores.getZkController().getZkStateReader().registerCore(collectionName);
+ // for the watcher, only remove on collection deletion (ie collection == null), since
+ // watch from coordinator is collection specific
+ solrCall
+ .cores
+ .getZkController()
+ .getZkStateReader()
+ .registerDocCollectionWatcher(collectionName, collection -> collection == null);
if (log.isDebugEnabled()) {
log.debug("coordinator node, returns synthetic core: {}", core.getName());
}
diff --git a/solr/core/src/test/org/apache/solr/common/cloud/ZkStateReaderAccessor.java b/solr/core/src/test/org/apache/solr/common/cloud/ZkStateReaderAccessor.java
index 0b51b1d9c2d..c5b8d02ef2c 100644
--- a/solr/core/src/test/org/apache/solr/common/cloud/ZkStateReaderAccessor.java
+++ b/solr/core/src/test/org/apache/solr/common/cloud/ZkStateReaderAccessor.java
@@ -16,6 +16,7 @@
*/
package org.apache.solr.common.cloud;
+import java.util.Collections;
import java.util.Set;
/** Helper class to access package-private methods from ZkStateReader. */
@@ -29,4 +30,8 @@ public class ZkStateReaderAccessor {
public Set<DocCollectionWatcher> getStateWatchers(String collection) {
return zkStateReader.getStateWatchers(collection);
}
+
+ public Set<String> getWatchedCollections() {
+ return Collections.unmodifiableSet(zkStateReader.getCollectionWatches().keySet());
+ }
}
diff --git a/solr/core/src/test/org/apache/solr/search/TestCoordinatorRole.java b/solr/core/src/test/org/apache/solr/search/TestCoordinatorRole.java
index d164a7b1bbc..705429de5e5 100644
--- a/solr/core/src/test/org/apache/solr/search/TestCoordinatorRole.java
+++ b/solr/core/src/test/org/apache/solr/search/TestCoordinatorRole.java
@@ -25,6 +25,7 @@ import java.util.Date;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
+import java.util.Objects;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.ExecutorService;
@@ -47,6 +48,8 @@ import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.cloud.DocCollection;
import org.apache.solr.common.cloud.Replica;
+import org.apache.solr.common.cloud.ZkStateReader;
+import org.apache.solr.common.cloud.ZkStateReaderAccessor;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.params.ShardParams;
import org.apache.solr.common.util.ExecutorUtil;
@@ -411,4 +414,53 @@ public class TestCoordinatorRole extends SolrCloudTestCase {
assertTrue(found);
return (String) docs.get(0).getFieldValue("_core_");
}
+
+ public void testWatch() throws Exception {
+ final int DATA_NODE_COUNT = 2;
+ MiniSolrCloudCluster cluster =
+ configureCluster(DATA_NODE_COUNT)
+ .addConfig("conf1", configset("cloud-minimal"))
+ .configure();
+ final String TEST_COLLECTION = "c1";
+
+ try {
+ CloudSolrClient client = cluster.getSolrClient();
+ CollectionAdminRequest.createCollection(TEST_COLLECTION, "conf1", 1, 2).process(client);
+ cluster.waitForActiveCollection(TEST_COLLECTION, 1, 2);
+ System.setProperty(NodeRoles.NODE_ROLES_PROP, "coordinator:on");
+ JettySolrRunner coordinatorJetty;
+ try {
+ coordinatorJetty = cluster.startJettySolrRunner();
+ } finally {
+ System.clearProperty(NodeRoles.NODE_ROLES_PROP);
+ }
+
+ ZkStateReader zkStateReader =
+ coordinatorJetty.getCoreContainer().getZkController().getZkStateReader();
+ ZkStateReaderAccessor zkWatchAccessor = new ZkStateReaderAccessor(zkStateReader);
+
+ // no watch at first
+ assertTrue(!zkWatchAccessor.getWatchedCollections().contains(TEST_COLLECTION));
+ new QueryRequest(new SolrQuery("*:*"))
+ .setPreferredNodes(List.of(coordinatorJetty.getNodeName()))
+ .process(client, TEST_COLLECTION);
+
+ // now it should be watching it after the query
+ assertTrue(zkWatchAccessor.getWatchedCollections().contains(TEST_COLLECTION));
+
+ CollectionAdminRequest.deleteReplica(TEST_COLLECTION, "shard1", 1).process(client);
+ cluster.waitForActiveCollection(TEST_COLLECTION, 1, 1);
+
+ // still one replica left, should not remove the watch
+ assertTrue(zkWatchAccessor.getWatchedCollections().contains(TEST_COLLECTION));
+
+ CollectionAdminRequest.deleteCollection(TEST_COLLECTION).process(client);
+ zkStateReader.waitForState(TEST_COLLECTION, 30, TimeUnit.SECONDS, Objects::isNull);
+
+ // watch should be removed after collection deletion
+ assertTrue(!zkWatchAccessor.getWatchedCollections().contains(TEST_COLLECTION));
+ } finally {
+ cluster.shutdown();
+ }
+ }
}
diff --git a/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkStateReader.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkStateReader.java
index 0074ab74762..d8115fdf1b8 100644
--- a/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkStateReader.java
+++ b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkStateReader.java
@@ -1977,6 +1977,11 @@ public class ZkStateReader implements SolrCloseable {
return watchers;
}
+ /* package-private for testing*/
+ Map<String, StatefulCollectionWatch> getCollectionWatches() {
+ return Collections.unmodifiableMap(collectionWatches.statefulWatchesByCollectionName);
+ }
+
public void registerCollectionPropsWatcher(
final String collection, CollectionPropsWatcher propsWatcher) {
AtomicBoolean watchSet = new AtomicBoolean(false);