Skip to content

Commit 3792f2d

Browse files
authored
SOLR-18174 AsyncTracker Semaphore permit leak fix (#4236)
Also add metric solr_client_request_async_permits Make max async requests configurable with sysprop solr.solrj.http.jetty.async_requests.max
1 parent 576d2ea commit 3792f2d

7 files changed

Lines changed: 526 additions & 9 deletions

File tree

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
title: Fix semaphore permit leaks in HttpJettySolrClient's AsyncTracker. Avoid IO-thread deadlock on connection failure retries. Add a new metric gauge solr.http.client.async_permits
2+
type: fixed
3+
authors:
4+
- name: Jan Høydahl
5+
url: https://home.apache.org/phonebook.html?uid=janhoy
6+
links:
7+
- name: SOLR-18174
8+
url: https://issues.apache.org/jira/browse/SOLR-18174

solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static org.apache.solr.util.stats.InstrumentedHttpListenerFactory.KNOWN_METRIC_NAME_STRATEGIES;
2020

2121
import io.opentelemetry.api.common.Attributes;
22+
import io.opentelemetry.api.metrics.ObservableLongGauge;
2223
import java.lang.invoke.MethodHandles;
2324
import java.util.Iterator;
2425
import java.util.List;
@@ -85,6 +86,7 @@ public class HttpShardHandlerFactory extends ShardHandlerFactory
8586
protected volatile HttpJettySolrClient defaultClient;
8687
protected InstrumentedHttpListenerFactory httpListenerFactory;
8788
protected LBAsyncSolrClient loadbalancer;
89+
private ObservableLongGauge asyncRequestsGauge;
8890

8991
int corePoolSize = 0;
9092
int maximumPoolSize = Integer.MAX_VALUE;
@@ -352,6 +354,7 @@ public void close() {
352354
ExecutorUtil.shutdownAndAwaitTermination(commExecutor);
353355
}
354356
}
357+
IOUtils.closeQuietly(asyncRequestsGauge);
355358
try {
356359
SolrMetricProducer.super.close();
357360
} catch (Exception e) {
@@ -440,5 +443,20 @@ public void initializeMetrics(SolrMetricsContext parentContext, Attributes attri
440443
commExecutor =
441444
solrMetricsContext.instrumentedExecutorService(
442445
commExecutor, "solr.core.executor", "httpShardExecutor", SolrInfoBean.Category.QUERY);
446+
if (defaultClient != null) {
447+
asyncRequestsGauge =
448+
solrMetricsContext.observableLongGauge(
449+
"solr.client.request.async_permits",
450+
"Outstanding async HTTP request permits in the Jetty SolrJ client"
451+
+ " (state=max: configured ceiling; state=available: currently unused permits).",
452+
measurement -> {
453+
measurement.record(
454+
defaultClient.asyncTrackerMaxPermits(), Attributes.of(STATE_KEY_ATTR, "max"));
455+
measurement.record(
456+
defaultClient.asyncTrackerAvailablePermits(),
457+
Attributes.of(STATE_KEY_ATTR, "available"));
458+
},
459+
null);
460+
}
443461
}
444462
}

0 commit comments

Comments
 (0)