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

Reply via email to