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 11878d79118 SOLR-16636: ZkStateReader.waitForState should not register
a watch if state already matches predicate (#1318)
11878d79118 is described below
commit 11878d79118d0335c0e4da5a0702d0b607776a4c
Author: Noble Paul <[email protected]>
AuthorDate: Mon Feb 6 16:50:15 2023 +1100
SOLR-16636: ZkStateReader.waitForState should not register a watch if state
already matches predicate (#1318)
---
.../apache/solr/common/cloud/ZkStateReader.java | 41 +++++++++++++++++++++-
.../org/apache/solr/common/cloud/ClusterState.java | 8 +++++
2 files changed, 48 insertions(+), 1 deletion(-)
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 d714dfee54c..c7173173ef2 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
@@ -832,6 +832,11 @@ public class ZkStateReader implements SolrCloseable {
return cachedDocCollection;
}
+ @Override
+ public DocCollection getOrNull() {
+ return cachedDocCollection;
+ }
+
@Override
public boolean isLazilyLoaded() {
return true;
@@ -1682,6 +1687,37 @@ public class ZkStateReader implements SolrCloseable {
}
}
+ /**
+ * fetch the collection that is already cached. This may return a null if it
is not already cached
+ * This is an optimization to avoid fetching state if it is not modified.
this is particularly
+ * true for PRS collections where state is rarely modified
+ */
+ private DocCollection fetchCachedCollection(String coll) {
+ String collectionPath = DocCollection.getCollectionPath(coll);
+ DocCollection c = null;
+ ClusterState.CollectionRef ref = clusterState.getCollectionRef(coll);
+ if (ref == null) return null;
+ c = ref.getOrNull();
+ if (c == null) return null;
+ Stat stat = null;
+ try {
+ stat = zkClient.exists(collectionPath, null, false);
+ } catch (Exception e) {
+ return null;
+ }
+ if (stat != null) {
+ if (!c.isModified(stat.getVersion(), stat.getCversion())) {
+ // we have the latest collection state
+ return c;
+ }
+ if (c.isPerReplicaState() && c.getChildNodesVersion() <
stat.getCversion()) {
+ // only PRS is modified. just fetch it and return the new collection
+ return c.copyWith(PerReplicaStatesFetcher.fetch(collectionPath,
zkClient, null));
+ }
+ }
+ return null;
+ }
+
private DocCollection fetchCollectionState(String coll, Watcher watcher)
throws KeeperException, InterruptedException {
String collectionPath = DocCollection.getCollectionPath(coll);
@@ -1869,6 +1905,8 @@ public class ZkStateReader implements SolrCloseable {
if (closed) {
throw new AlreadyClosedException();
}
+ DocCollection coll = fetchCachedCollection(collection);
+ if (coll != null && predicate.matches(liveNodes, coll)) return;
final CountDownLatch latch = new CountDownLatch(1);
waitLatches.add(latch);
@@ -1922,7 +1960,8 @@ public class ZkStateReader implements SolrCloseable {
if (closed) {
throw new AlreadyClosedException();
}
-
+ DocCollection coll = fetchCachedCollection(collection);
+ if (coll != null && predicate.test(coll)) return coll;
final CountDownLatch latch = new CountDownLatch(1);
waitLatches.add(latch);
AtomicReference<DocCollection> docCollection = new AtomicReference<>();
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java
b/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java
index cda0b66a9e6..22c14473f2c 100644
--- a/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java
+++ b/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java
@@ -391,6 +391,14 @@ public class ClusterState implements JSONWriter.Writable {
protected final AtomicInteger gets = new AtomicInteger();
private final DocCollection coll;
+ /**
+ * return the collection if it is already loaded. lazy references may
return null if it is not
+ * loaded already
+ */
+ public DocCollection getOrNull() {
+ return coll;
+ }
+
public int getCount() {
return gets.get();
}