You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by no...@apache.org on 2022/06/23 04:24:24 UTC

[lucene-solr] branch jira/solr15138-3 updated: optimize wait for state

This is an automated email from the ASF dual-hosted git repository.

noble pushed a commit to branch jira/solr15138-3
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git


The following commit(s) were added to refs/heads/jira/solr15138-3 by this push:
     new 8b05e7a756d optimize wait for state
8b05e7a756d is described below

commit 8b05e7a756d2940942c839e01809642f608162b6
Author: Noble Paul <no...@gmail.com>
AuthorDate: Thu Jun 23 14:24:10 2022 +1000

    optimize wait for state
---
 .../java/org/apache/solr/handler/ClusterAPI.java   |  4 +-
 .../src/java/org/apache/solr/common/Timer.java     | 66 +++++++++++++++++++---
 .../apache/solr/common/cloud/ZkStateReader.java    | 19 +++++++
 3 files changed, 78 insertions(+), 11 deletions(-)

diff --git a/solr/core/src/java/org/apache/solr/handler/ClusterAPI.java b/solr/core/src/java/org/apache/solr/handler/ClusterAPI.java
index 685476702e4..08b786edbe5 100644
--- a/solr/core/src/java/org/apache/solr/handler/ClusterAPI.java
+++ b/solr/core/src/java/org/apache/solr/handler/ClusterAPI.java
@@ -81,13 +81,13 @@ public class ClusterAPI {
   @EndPoint(method = GET,
       path = "/node/create_times",
       permission = COLL_READ_PERM)
-  public void createTime(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception {
+  public void createTime(SolrQueryRequest req, SolrQueryResponse rsp) {
     rsp.add("create_times",CreateCollectionCmd.T);
   }
   @EndPoint(method = GET,
       path = "/node/core_create_times",
       permission = COLL_READ_PERM)
-  public void coreCreateTime(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception {
+  public void coreCreateTime(SolrQueryRequest req, SolrQueryResponse rsp) {
     rsp.add("core_create_times",collectionsHandler.getCoreContainer().timers);
   }
 
diff --git a/solr/solrj/src/java/org/apache/solr/common/Timer.java b/solr/solrj/src/java/org/apache/solr/common/Timer.java
index 41435f60d8d..9f607d471fc 100644
--- a/solr/solrj/src/java/org/apache/solr/common/Timer.java
+++ b/solr/solrj/src/java/org/apache/solr/common/Timer.java
@@ -19,12 +19,15 @@ package org.apache.solr.common;
 
 import java.io.IOException;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Stack;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.BiConsumer;
 
 import org.apache.solr.common.annotation.JsonProperty;
 import org.apache.solr.common.util.ReflectMapWriter;
@@ -49,10 +52,18 @@ public class Timer implements ReflectMapWriter {
   @JsonProperty
   public AtomicLong min;
 
-  final TimerBag inst;
+  final TimerBag timerBag;
+
+  String parent;
+
 
   Timer(TimerBag inst) {
-    this.inst = inst;
+    this.timerBag = inst;
+    if(inst != null) {
+      if(!inst.callStack.isEmpty()) {
+        parent = inst.callStack.peek();
+      }
+    }
     if (inst != null && inst.isCumulative) {
       max = new AtomicLong(0);
       min = new AtomicLong(0);
@@ -63,7 +74,10 @@ public class Timer implements ReflectMapWriter {
   @Override
   public void writeMap(EntryWriter ew) throws IOException {
     ReflectMapWriter.super.writeMap(ew);
-    if (inst != null && inst.isCumulative) {
+    if (startL > 0) {
+      ew.put("elapsed", "" + (System.currentTimeMillis() - startL) + "ms");
+    }
+    if (timerBag != null && timerBag.isCumulative) {
       if (times.get() > 0) {
         long avg = totalTimeTaken.get() / times.get();
         ew.put("avg", avg);
@@ -83,6 +97,9 @@ public class Timer implements ReflectMapWriter {
     public Map<String, Timer> timers;
     public boolean isCumulative;
 
+    Stack<String> callStack = new Stack<>();
+
+
     public void start(String name) {
       init();
       Timer t = timers.get(name);
@@ -94,6 +111,7 @@ public class Timer implements ReflectMapWriter {
       t.times.incrementAndGet();
       t.startL = System.currentTimeMillis();
       t.currentStart = new Date(t.startL).toString();
+      callStack.push(name);
     }
 
     public TimerBag init() {
@@ -106,6 +124,9 @@ public class Timer implements ReflectMapWriter {
     public void end(String name) {
       init();
       Timer c = timers.get(name);
+      while (!callStack.isEmpty()) {
+        if(name.equals(callStack.pop())) break;
+      }
       if (c != null) c.end();
     }
 
@@ -114,11 +135,12 @@ public class Timer implements ReflectMapWriter {
       if (t != null) {
         if (timers == null) timers = new ConcurrentHashMap<>();
         t.forEach((name, timer) -> {
-          Timer old = timers.computeIfAbsent(name, s -> new Timer(this));
-          old.times.incrementAndGet();
-          old.totalTimeTaken.addAndGet(timer.lastTimeTaken);
-          old.max.set(Math.max(old.max.get(), timer.lastTimeTaken));
-          old.min.set(Math.min(old.min.get(), timer.lastTimeTaken));
+          Timer cumulative = timers.computeIfAbsent(name, s -> new Timer(this));
+          cumulative.times.incrementAndGet();
+          cumulative.totalTimeTaken.addAndGet(timer.lastTimeTaken);
+          cumulative.max.set(Math.max(cumulative.max.get(), timer.lastTimeTaken));
+          cumulative.min.set(Math.min(cumulative.min.get(), timer.lastTimeTaken));
+          cumulative.parent = timer.parent;
         });
       }
     }
@@ -158,10 +180,12 @@ public class Timer implements ReflectMapWriter {
         INST.set(bag);
       }
       inflight.add(INST.get());
+      start("ROOT");
       return bag;
     }
 
     public void destroy() {
+      end("ROOT");
       TimerBag inst = INST.get();
       if (inst == null) return;
       cumulative.add(inst);
@@ -170,8 +194,32 @@ public class Timer implements ReflectMapWriter {
 
     @Override
     public void writeMap(EntryWriter ew) throws IOException {
-      ew.put("cumulative", cumulative);
+
+      Timer root = cumulative.timers.get("ROOT");
+      ew.putIfNotNull("cumulative", root==null? null: new Tree(root, "ROOT", cumulative.timers));
       ew.put("inflight", inflight);
     }
+    static class Tree implements MapWriter {
+      Timer root;
+      Map<String,Tree> kids;
+
+      Tree(Timer root, String name, Map<String, Timer> timers) {
+        this.root = root;
+        timers.forEach((s, t) -> {
+          if(name.equals(t.parent)) {
+            if(kids == null) kids = new HashMap<>();
+            kids.put(s, new Tree(t, s,timers));
+          }
+        });
+
+      }
+
+      @Override
+      public void writeMap(EntryWriter ew) throws IOException {
+        root.writeMap(ew);
+        ew.putIfNotNull("_", kids);
+      }
+    }
+
   }
 }
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java b/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java
index a7acd5d9414..1fa7487fadc 100644
--- a/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java
+++ b/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java
@@ -1883,6 +1883,25 @@ public class ZkStateReader implements SolrCloseable {
     final CountDownLatch latch = new CountDownLatch(1);
     waitLatches.add(latch);
     AtomicReference<DocCollection> docCollection = new AtomicReference<>();
+    DocCollection currentColl = clusterState.getCollection(collection);
+    if (currentColl != null) {
+      //we really wish to avoid the watches
+      if (predicate.test(currentColl)) {
+        return;
+      }
+      Stat stat = null;
+      try {
+        stat = zkClient.exists(getCollectionPath(collection), null, true);
+        if (stat != null && currentColl.isModified(stat.getVersion(), stat.getCversion())) {
+          //this is already modified and we should fetch a fresh copy
+          DocCollection c = getCollectionLive(this, collection);
+          if (c != null && predicate.test(c)) return;
+        }
+      } catch (KeeperException e) {
+        //go ahead with a collection watch
+      }
+    }
+
     DocCollectionWatcher watcher = (c) -> {
       docCollection.set(c);
       boolean matches = predicate.test(c);