From ff2729d411055ca135703e6dccea4932538dec5e Mon Sep 17 00:00:00 2001 From: Rohit Yadav Date: Fri, 6 May 2016 10:14:47 +0530 Subject: [PATCH] CLOUDSTACK-9348: Optimize NioTest and NioConnection main loop - Reduces SSL handshake timeout to 15s, previously this was only 10s in commit debfcdef788ce0d51be06db0ef10f6815f9b563b - Adds an aggresive explicit wakeup to save the Nio main IO loop/handler from getting blocked - Fix NioTest to fail/succeed in about 60s, previously this was 300s - Due to aggresive wakeup usage, NioTest should complete in less than 5s on most systems. On virtualized environment this may slightly increase due to thread, CPU burst/scheduling delays. Signed-off-by: Rohit Yadav --- utils/src/com/cloud/utils/nio/Link.java | 4 +-- .../com/cloud/utils/nio/NioConnection.java | 2 ++ .../com/cloud/utils/testcase/NioTest.java | 27 ++++++++++--------- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/utils/src/com/cloud/utils/nio/Link.java b/utils/src/com/cloud/utils/nio/Link.java index cc6a27f19ed..729af6c0d02 100755 --- a/utils/src/com/cloud/utils/nio/Link.java +++ b/utils/src/com/cloud/utils/nio/Link.java @@ -598,8 +598,8 @@ public class Link { while (handshakeStatus != SSLEngineResult.HandshakeStatus.FINISHED && handshakeStatus != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) { final long timeTaken = System.currentTimeMillis() - startTimeMills; - if (timeTaken > 60000L) { - s_logger.warn("SSL Handshake has taken more than 60s to connect to: " + socketChannel.getRemoteAddress() + + if (timeTaken > 15000L) { + s_logger.warn("SSL Handshake has taken more than 15s to connect to: " + socketChannel.getRemoteAddress() + ". Please investigate this connection."); return false; } diff --git a/utils/src/com/cloud/utils/nio/NioConnection.java b/utils/src/com/cloud/utils/nio/NioConnection.java index 5040ab1d567..fa92959e3e0 100755 --- a/utils/src/com/cloud/utils/nio/NioConnection.java +++ b/utils/src/com/cloud/utils/nio/NioConnection.java @@ -170,6 +170,8 @@ public abstract class NioConnection implements Runnable { processTodos(); } catch (Throwable e) { s_logger.warn("Caught an exception but continuing on.", e); + } finally { + _selector.wakeup(); } } synchronized (_thread) { diff --git a/utils/test/com/cloud/utils/testcase/NioTest.java b/utils/test/com/cloud/utils/testcase/NioTest.java index 3c001ddaff0..515119d9e7e 100644 --- a/utils/test/com/cloud/utils/testcase/NioTest.java +++ b/utils/test/com/cloud/utils/testcase/NioTest.java @@ -60,9 +60,9 @@ public class NioTest { private static final Logger LOGGER = Logger.getLogger(NioTest.class); // Test should fail in due time instead of looping forever - private static final int TESTTIMEOUT = 120000; + private static final int TESTTIMEOUT = 60000; - final private int totalTestCount = 5; + final private int totalTestCount = 4; private int completedTestCount = 0; private NioServer server; @@ -70,7 +70,7 @@ public class NioTest { private List maliciousClients = new ArrayList<>(); private ExecutorService clientExecutor = Executors.newFixedThreadPool(totalTestCount, new NamedThreadFactory("NioClientHandler"));; - private ExecutorService maliciousExecutor = Executors.newFixedThreadPool(5*totalTestCount, new NamedThreadFactory("MaliciousNioClientHandler"));; + private ExecutorService maliciousExecutor = Executors.newFixedThreadPool(totalTestCount, new NamedThreadFactory("MaliciousNioClientHandler"));; private Random randomGenerator = new Random(); private byte[] testBytes; @@ -97,7 +97,6 @@ public class NioTest { testBytes = new byte[1000000]; randomGenerator.nextBytes(testBytes); - // Server configured with one worker server = new NioServer("NioTestServer", 0, 1, new NioTestServer()); try { server.start(); @@ -105,13 +104,18 @@ public class NioTest { Assert.fail(e.getMessage()); } - // 5 malicious clients per valid client + /** + * The malicious client(s) tries to block NioServer's main IO loop + * thread until SSL handshake timeout value (from Link class, 15s) after + * which the valid NioClient(s) get the opportunity to make connection(s) + */ + for (int i = 0; i < totalTestCount; i++) { + final NioClient maliciousClient = new NioMaliciousClient("NioMaliciousTestClient-" + i, "127.0.0.1", server.getPort(), 1, new NioMaliciousTestClient()); + maliciousClients.add(maliciousClient); + maliciousExecutor.submit(new ThreadedNioClient(maliciousClient)); + } + for (int i = 0; i < totalTestCount; i++) { - for (int j = 0; j < 5; j++) { - final NioClient maliciousClient = new NioMaliciousClient("NioMaliciousTestClient-" + i, "127.0.0.1", server.getPort(), 1, new NioMaliciousTestClient()); - maliciousClients.add(maliciousClient); - maliciousExecutor.submit(new ThreadedNioClient(maliciousClient)); - } final NioClient client = new NioClient("NioTestClient-" + i, "127.0.0.1", server.getPort(), 1, new NioTestClient()); clients.add(client); clientExecutor.submit(new ThreadedNioClient(client)); @@ -199,7 +203,7 @@ public class NioTest { _selector.close(); throw e; } catch (InterruptedException e) { - LOGGER.trace(e.getMessage()); + LOGGER.debug(e.getMessage()); } } } @@ -287,7 +291,6 @@ public class NioTest { LOGGER.info("Server: Received OTHER task"); } } - } } }