From ab82089aed8329d23e1315a84984061a61ab0ce6 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 5 Jan 2016 09:35:04 +0100 Subject: [server] Allow httpd to handle more than two concurrent connections Had I read the javadocs properly I would have noticed that the thread pool only starts growing to its maximum size if the queue is full, not the other way round. So now we use a modified thread pool borrowed from SO that does exactly that. --- .../src/main/java/fi/iki/elonen/NanoHTTPD.java | 23 +++++++-- .../bwlp/sat/util/GrowingThreadPoolExecutor.java | 60 ++++++++++++++++++++++ 2 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/util/GrowingThreadPoolExecutor.java diff --git a/dozentenmodulserver/src/main/java/fi/iki/elonen/NanoHTTPD.java b/dozentenmodulserver/src/main/java/fi/iki/elonen/NanoHTTPD.java index ff552e83..7b437414 100644 --- a/dozentenmodulserver/src/main/java/fi/iki/elonen/NanoHTTPD.java +++ b/dozentenmodulserver/src/main/java/fi/iki/elonen/NanoHTTPD.java @@ -63,13 +63,13 @@ import java.util.StringTokenizer; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import org.apache.commons.io.output.ByteArrayOutputStream; import org.apache.log4j.Logger; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; +import org.openslx.bwlp.sat.util.GrowingThreadPoolExecutor; /** * A simple, tiny, nicely embeddable HTTP server in Java @@ -131,7 +131,7 @@ public abstract class NanoHTTPD implements Runnable { * This is required as the Keep-Alive HTTP connections would otherwise * block the socket reading thread forever (or as long the browser is open). */ - public static final int SOCKET_READ_TIMEOUT = 15000; + public static final int SOCKET_READ_TIMEOUT = 10000; /** * Common MIME type for dynamic content: plain text */ @@ -201,21 +201,26 @@ public abstract class NanoHTTPD implements Runnable { do { try { final Socket finalAccept = myServerSocket.accept(); + LOGGER.info("Accepted connection"); registerConnection(finalAccept); finalAccept.setSoTimeout(SOCKET_READ_TIMEOUT); final InputStream inputStream = finalAccept.getInputStream(); asyncRunner.exec(new Runnable() { @Override public void run() { + LOGGER.info("Starting worker"); OutputStream outputStream = null; try { outputStream = finalAccept.getOutputStream(); HTTPSession session = new HTTPSession(inputStream, outputStream, finalAccept.getInetAddress()); - while (!finalAccept.isClosed()) { + while (!finalAccept.isClosed() && !finalAccept.isInputShutdown()) { + LOGGER.info("Pre-execute"); session.execute(); + LOGGER.info("Post-execute"); } } catch (Exception e) { + LOGGER.info("Post-execute (ex)"); // When the socket is closed by the client, we throw our own SocketException // to break the "keep alive" loop above. if (!(e instanceof SocketTimeoutException) @@ -227,6 +232,7 @@ public abstract class NanoHTTPD implements Runnable { safeClose(inputStream); safeClose(finalAccept); unRegisterConnection(finalAccept); + LOGGER.info("Finished worker"); } } }); @@ -457,7 +463,7 @@ public abstract class NanoHTTPD implements Runnable { *
*/ public static class DefaultAsyncRunner implements AsyncRunner { - private ExecutorService pool = new ThreadPoolExecutor(2, 16, 1, TimeUnit.MINUTES, + private ExecutorService pool = new GrowingThreadPoolExecutor(2, 16, 1, TimeUnit.MINUTES, new ArrayBlockingQueue