diff --git a/docs/apidiffs/current_vs_latest/prometheus-metrics-exporter-httpserver.txt b/docs/apidiffs/current_vs_latest/prometheus-metrics-exporter-httpserver.txt index 17fccaa45..8bc12b84f 100644 --- a/docs/apidiffs/current_vs_latest/prometheus-metrics-exporter-httpserver.txt +++ b/docs/apidiffs/current_vs_latest/prometheus-metrics-exporter-httpserver.txt @@ -1,2 +1,4 @@ Comparing source compatibility of prometheus-metrics-exporter-httpserver-1.8.1-SNAPSHOT.jar against prometheus-metrics-exporter-httpserver-1.8.0.jar -No changes. +*** MODIFIED CLASS: PUBLIC io.prometheus.metrics.exporter.httpserver.HTTPServer (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + diff --git a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/BlockingRejectedExecutionHandler.java b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/BlockingRejectedExecutionHandler.java deleted file mode 100644 index 023d3f2f0..000000000 --- a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/BlockingRejectedExecutionHandler.java +++ /dev/null @@ -1,18 +0,0 @@ -package io.prometheus.metrics.exporter.httpserver; - -import java.util.concurrent.RejectedExecutionHandler; -import java.util.concurrent.ThreadPoolExecutor; - -class BlockingRejectedExecutionHandler implements RejectedExecutionHandler { - - @Override - public void rejectedExecution(Runnable runnable, ThreadPoolExecutor threadPoolExecutor) { - if (!threadPoolExecutor.isShutdown()) { - try { - threadPoolExecutor.getQueue().put(runnable); - } catch (InterruptedException ignored) { - // ignore - } - } - } -} diff --git a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java index e93b122b0..ff43144f0 100644 --- a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java +++ b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java @@ -12,14 +12,13 @@ import io.prometheus.metrics.model.registry.PrometheusRegistry; import java.io.Closeable; import java.io.IOException; -import java.io.InputStream; import java.net.InetAddress; import java.net.InetSocketAddress; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; +import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; -import java.util.concurrent.SynchronousQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import javax.annotation.Nullable; @@ -39,6 +38,10 @@ @StableApi public class HTTPServer implements Closeable { + private static final int DEFAULT_MIN_THREADS = 10; + private static final int DEFAULT_MAX_THREADS = 10; + private static final int DEFAULT_QUEUE_SIZE = 100; + static { if (!System.getProperties().containsKey("sun.net.httpserver.maxReqTime")) { System.setProperty("sun.net.httpserver.maxReqTime", "60"); @@ -153,22 +156,14 @@ public void handle(HttpExchange exchange) throws IOException { } } } else { - drainInputAndClose(exchange); + exchange.getRequestBody().close(); exchange.sendResponseHeaders(403, -1); + exchange.close(); } } }; } - private void drainInputAndClose(HttpExchange httpExchange) throws IOException { - InputStream inputStream = httpExchange.getRequestBody(); - byte[] b = new byte[4096]; - while (inputStream.read(b) != -1) { - // nop - } - inputStream.close(); - } - /** Stop the HTTP server. Same as {@link #close()}. */ public void stop() { close(); @@ -337,13 +332,12 @@ private ExecutorService makeExecutorService() { return executorService; } else { return new ThreadPoolExecutor( - 1, - 10, + DEFAULT_MIN_THREADS, + DEFAULT_MAX_THREADS, 120, TimeUnit.SECONDS, - new SynchronousQueue<>(true), - NamedDaemonThreadFactory.defaultThreadFactory(true), - new BlockingRejectedExecutionHandler()); + new ArrayBlockingQueue<>(DEFAULT_QUEUE_SIZE), + NamedDaemonThreadFactory.defaultThreadFactory(true)); } } diff --git a/prometheus-metrics-exporter-httpserver/src/test/java/io/prometheus/metrics/exporter/httpserver/HTTPServerTest.java b/prometheus-metrics-exporter-httpserver/src/test/java/io/prometheus/metrics/exporter/httpserver/HTTPServerTest.java index ff2d55048..1106e5e19 100644 --- a/prometheus-metrics-exporter-httpserver/src/test/java/io/prometheus/metrics/exporter/httpserver/HTTPServerTest.java +++ b/prometheus-metrics-exporter-httpserver/src/test/java/io/prometheus/metrics/exporter/httpserver/HTTPServerTest.java @@ -25,6 +25,7 @@ import java.security.Principal; import java.util.List; import java.util.concurrent.Executors; +import java.util.concurrent.ThreadPoolExecutor; import javax.net.ssl.SSLContext; import javax.security.auth.Subject; import org.junit.jupiter.api.BeforeEach; @@ -45,7 +46,7 @@ void setUp() { } @Test - public void testSubjectDoAs() throws Exception { + void testSubjectDoAs() throws Exception { final String user = "joe"; final Subject subject = new Subject(); subject.getPrincipals().add(() -> user); @@ -158,6 +159,22 @@ void metricsCustomRootPath() throws Exception { "my_counter_total 1.0"); } + @Test + void defaultExecutorHasBoundedQueueAndNonBlockingRejection() throws Exception { + HTTPServer server = HTTPServer.builder().port(0).buildAndStart(); + try { + assertThat(server.executorService).isInstanceOf(ThreadPoolExecutor.class); + ThreadPoolExecutor executor = (ThreadPoolExecutor) server.executorService; + assertThat(executor.getCorePoolSize()).isEqualTo(10); + assertThat(executor.getMaximumPoolSize()).isEqualTo(10); + assertThat(executor.getQueue().remainingCapacity()).isEqualTo(100); + assertThat(executor.getRejectedExecutionHandler()) + .isInstanceOf(ThreadPoolExecutor.AbortPolicy.class); + } finally { + server.stop(); + } + } + @Test void registryThrows() throws Exception { HTTPServer server =