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

asalamon74 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 d763800  SOLR-15301: Eliminate repetitive index size calculation for 
Solr metrics (#326)
d763800 is described below

commit d7638006265a8f651b8c0a922d60828293fb5874
Author: Andras Salamon <[email protected]>
AuthorDate: Thu Oct 7 08:27:23 2021 +0200

    SOLR-15301: Eliminate repetitive index size calculation for Solr metrics 
(#326)
    
    Replacing own ThreadLocal implementation with SolrRequestInfo
---
 .../src/java/org/apache/solr/core/SolrCore.java    | 39 +++++++++++-----------
 .../apache/solr/handler/ReplicationHandler.java    |  2 +-
 .../apache/solr/handler/admin/MetricsHandler.java  | 10 ++++--
 3 files changed, 28 insertions(+), 23 deletions(-)

diff --git a/solr/core/src/java/org/apache/solr/core/SolrCore.java 
b/solr/core/src/java/org/apache/solr/core/SolrCore.java
index 79a78a6..55e1dc3 100644
--- a/solr/core/src/java/org/apache/solr/core/SolrCore.java
+++ b/solr/core/src/java/org/apache/solr/core/SolrCore.java
@@ -117,6 +117,7 @@ import org.apache.solr.pkg.PackageLoader;
 import org.apache.solr.pkg.PackagePluginHolder;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.request.SolrRequestHandler;
+import org.apache.solr.request.SolrRequestInfo;
 import org.apache.solr.response.BinaryResponseWriter;
 import org.apache.solr.response.CSVResponseWriter;
 import org.apache.solr.response.GeoJSONResponseWriter;
@@ -470,9 +471,14 @@ public final class SolrCore implements SolrInfoBean, 
Closeable {
     return indexReaderFactory;
   }
 
-  private ThreadLocal<Long> indexSize = new ThreadLocal<>();
-
-  public long getIndexSize() {
+  /**
+   * Recalculates the index size.
+   *
+   * Should only be called from {@code getIndexSize}.
+   *
+   * @return The index size in bytes.
+   */
+  private long calculateIndexSize() {
     Directory dir;
     long size = 0;
     try {
@@ -490,23 +496,18 @@ public final class SolrCore implements SolrInfoBean, 
Closeable {
     return size;
   }
 
-  public long getCachedIndexSize() {
-    if (indexSize.get() == null) {
-      if (log.isDebugEnabled()) {
-        log.debug("Recalculating index size for {}", getName());
-      }
-      indexSize.set(getIndexSize());
-    } else if (log.isDebugEnabled()) {
-      log.debug("reusing previous index size for {}", getName());
+  public long getIndexSize() {
+    SolrRequestInfo requestInfo = SolrRequestInfo.getRequestInfo();
+    if (requestInfo != null) {
+      return 
(Long)requestInfo.getReq().getContext().computeIfAbsent(cachedIndexSizeKeyName(),
 key -> calculateIndexSize());
+    } else {
+      return calculateIndexSize();
     }
-    return indexSize.get();
   }
 
-  public void clearIndexSizeCache() {
-    if (log.isDebugEnabled()) {
-      log.debug("Clearing index size cache for {}", getName());
-    }
-    indexSize.remove();
+  private String cachedIndexSizeKeyName() {
+    // avoid collision when we put index sizes for multiple cores in the same 
metrics request
+    return "indexSize_"+getName();
   }
 
   public int getSegmentCount() {
@@ -1230,9 +1231,9 @@ public final class SolrCore implements SolrInfoBean, 
Closeable {
     parentContext.gauge(() -> getOpenCount(), true, "refCount", 
Category.CORE.toString());
     parentContext.gauge(() -> getInstancePath().toString(), true, 
"instanceDir", Category.CORE.toString());
     parentContext.gauge(() -> isClosed() ? parentContext.nullString() : 
getIndexDir(), true, "indexDir", Category.CORE.toString());
-    parentContext.gauge(() -> isClosed() ? parentContext.nullNumber() : 
getCachedIndexSize(), true, "sizeInBytes", Category.INDEX.toString());
+    parentContext.gauge(() -> isClosed() ? parentContext.nullNumber() : 
getIndexSize(), true, "sizeInBytes", Category.INDEX.toString());
     parentContext.gauge(() -> isClosed() ? parentContext.nullNumber() : 
getSegmentCount(), true, "segments", Category.INDEX.toString());
-    parentContext.gauge(() -> isClosed() ? parentContext.nullString() : 
NumberUtils.readableSize(getCachedIndexSize()), true, "size", 
Category.INDEX.toString());
+    parentContext.gauge(() -> isClosed() ? parentContext.nullString() : 
NumberUtils.readableSize(getIndexSize()), true, "size", 
Category.INDEX.toString());
 
     final CloudDescriptor cd = getCoreDescriptor().getCloudDescriptor();
     if (cd != null) {
diff --git a/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java 
b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
index c8746f7..71fe0f4 100644
--- a/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
@@ -886,7 +886,7 @@ public class ReplicationHandler extends RequestHandlerBase 
implements SolrCoreAw
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String 
scope) {
     super.initializeMetrics(parentContext, scope);
-    solrMetricsContext.gauge(() -> (core != null && !core.isClosed() ? 
NumberUtils.readableSize(core.getCachedIndexSize()) : 
parentContext.nullString()),
+    solrMetricsContext.gauge(() -> (core != null && !core.isClosed() ? 
NumberUtils.readableSize(core.getIndexSize()) : parentContext.nullString()),
         true, "indexSize", getCategory().toString(), scope);
     solrMetricsContext.gauge(() -> (core != null && !core.isClosed() ? 
getIndexVersion().toString() : parentContext.nullString()),
          true, "indexVersion", getCategory().toString(), scope);
diff --git 
a/solr/core/src/java/org/apache/solr/handler/admin/MetricsHandler.java 
b/solr/core/src/java/org/apache/solr/handler/admin/MetricsHandler.java
index b46fbf5..77b9aa3 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/MetricsHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/MetricsHandler.java
@@ -50,6 +50,7 @@ import org.apache.solr.core.CoreContainer;
 import org.apache.solr.handler.RequestHandlerBase;
 import org.apache.solr.metrics.SolrMetricManager;
 import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.request.SolrRequestInfo;
 import org.apache.solr.response.SolrQueryResponse;
 import org.apache.solr.security.AuthorizationContext;
 import org.apache.solr.security.PermissionNameProvider;
@@ -108,8 +109,12 @@ public class MetricsHandler extends RequestHandlerBase 
implements PermissionName
     if (cc != null && AdminHandlersProxy.maybeProxyToNodes(req, rsp, cc)) {
       return; // Request was proxied to other node
     }
-
-    handleRequest(req.getParams(), (k, v) -> rsp.add(k, v));
+    SolrRequestInfo.setRequestInfo(new SolrRequestInfo(req, rsp));
+    try {
+      handleRequest(req.getParams(), (k, v) -> rsp.add(k, v));
+    } finally {
+      SolrRequestInfo.clearRequestInfo();
+    }
   }
   
   private void handleRequest(SolrParams params, BiConsumer<String, Object> 
consumer) throws Exception {
@@ -117,7 +122,6 @@ public class MetricsHandler extends RequestHandlerBase 
implements PermissionName
       consumer.accept("error", "metrics collection is disabled");
       return;
     }
-    cc.getCores().forEach((core) -> core.clearIndexSizeCache());
     boolean compact = params.getBool(COMPACT_PARAM, true);
     String[] keys = params.getParams(KEY_PARAM);
     if (keys != null && keys.length > 0) {

Reply via email to