From af4962f842d707a76b556539548e11239b24e4e9 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Mon, 12 Jun 2017 09:23:23 -0700 Subject: [PATCH] Issue #1605 - common executor and bufferpool for jsr356 client --- .../jsr356/JettyClientContainerProvider.java | 28 +++++++++++-- .../DelayedStartClientOnServerTest.java | 2 +- .../common/scopes/SimpleContainerScope.java | 41 ++++++++++++++----- 3 files changed, 57 insertions(+), 14 deletions(-) diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/JettyClientContainerProvider.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/JettyClientContainerProvider.java index 0d79cec5276..251d214abf0 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/JettyClientContainerProvider.java +++ b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/JettyClientContainerProvider.java @@ -19,14 +19,20 @@ package org.eclipse.jetty.websocket.jsr356; import java.lang.reflect.Method; +import java.util.concurrent.Executor; import javax.websocket.ContainerProvider; import javax.websocket.WebSocketContainer; +import org.eclipse.jetty.io.ByteBufferPool; +import org.eclipse.jetty.io.MappedByteBufferPool; import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.eclipse.jetty.util.thread.ShutdownThread; +import org.eclipse.jetty.websocket.api.WebSocketPolicy; +import org.eclipse.jetty.websocket.common.scopes.SimpleContainerScope; /** * Client {@link ContainerProvider} implementation. @@ -43,6 +49,8 @@ public class JettyClientContainerProvider extends ContainerProvider private static boolean useSingleton = false; private static WebSocketContainer INSTANCE; private static boolean useServerContainer = false; + private static Executor commonExecutor; + private static ByteBufferPool commonBufferPool; private static Object lock = new Object(); @@ -177,8 +185,22 @@ public class JettyClientContainerProvider extends ContainerProvider // Still no instance? if (webSocketContainer == null) { - // TODO: use cached Executor, ByteBufferPool, and HttpClient here - ClientContainer clientContainer = new ClientContainer(); + if (commonExecutor == null) + { + QueuedThreadPool threadPool = new QueuedThreadPool(); + String name = "Jsr356Client@" + hashCode(); + threadPool.setName(name); + threadPool.setDaemon(true); + commonExecutor = threadPool; + } + + if (commonBufferPool == null) + { + commonBufferPool = new MappedByteBufferPool(); + } + + SimpleContainerScope containerScope = new SimpleContainerScope(WebSocketPolicy.newClientPolicy(), commonBufferPool, commonExecutor, null); + ClientContainer clientContainer = new ClientContainer(containerScope); if (contextHandler != null && contextHandler instanceof ContainerLifeCycle) { @@ -192,7 +214,7 @@ public class JettyClientContainerProvider extends ContainerProvider // register JVM wide shutdown thread ShutdownThread.register(clientContainer); } - + if (!clientContainer.isStarted()) { try diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/DelayedStartClientOnServerTest.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/DelayedStartClientOnServerTest.java index 9a0282e4788..ac43e595d7d 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/DelayedStartClientOnServerTest.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/DelayedStartClientOnServerTest.java @@ -247,7 +247,7 @@ public class DelayedStartClientOnServerTest assertThat("Response", response, startsWith("Connected to ws://")); List threadNames = getThreadNames(server); assertNoHttpClientPoolThreads(threadNames); - assertThat("Threads", threadNames, hasItem(containsString("WebSocketContainer@"))); + assertThat("Threads", threadNames, hasItem(containsString("Jsr356Client@"))); } finally { diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/SimpleContainerScope.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/SimpleContainerScope.java index a82a7565584..5a8403022e3 100644 --- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/SimpleContainerScope.java +++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/SimpleContainerScope.java @@ -34,31 +34,52 @@ public class SimpleContainerScope extends ContainerLifeCycle implements WebSocke private final ByteBufferPool bufferPool; private final DecoratedObjectFactory objectFactory; private final WebSocketPolicy policy; - private Executor executor; + private final Executor executor; private SslContextFactory sslContextFactory; public SimpleContainerScope(WebSocketPolicy policy) { - this(policy,new MappedByteBufferPool(),new DecoratedObjectFactory()); + this(policy, new MappedByteBufferPool(), new DecoratedObjectFactory()); this.sslContextFactory = new SslContextFactory(); } public SimpleContainerScope(WebSocketPolicy policy, ByteBufferPool bufferPool) { - this(policy,bufferPool,new DecoratedObjectFactory()); + this(policy, bufferPool, new DecoratedObjectFactory()); } public SimpleContainerScope(WebSocketPolicy policy, ByteBufferPool bufferPool, DecoratedObjectFactory objectFactory) + { + this(policy, bufferPool, (Executor) null, objectFactory); + } + + public SimpleContainerScope(WebSocketPolicy policy, ByteBufferPool bufferPool, Executor executor, DecoratedObjectFactory objectFactory) { this.policy = policy; this.bufferPool = bufferPool; - this.objectFactory = objectFactory; - - QueuedThreadPool threadPool = new QueuedThreadPool(); - String name = "WebSocketContainer@" + hashCode(); - threadPool.setName(name); - threadPool.setDaemon(true); - this.executor = threadPool; + + if (objectFactory == null) + { + this.objectFactory = new DecoratedObjectFactory(); + } + else + { + this.objectFactory = objectFactory; + } + + if (executor == null) + { + QueuedThreadPool threadPool = new QueuedThreadPool(); + String name = "WebSocketContainer@" + hashCode(); + threadPool.setName(name); + threadPool.setDaemon(true); + this.executor = threadPool; + addBean(this.executor); + } + else + { + this.executor = executor; + } } @Override