From 30dc103a129d08304e1f1a99a84c045049de305d Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Tue, 18 Jun 2019 12:31:25 +1000 Subject: [PATCH] Issue #300 - manage deflater/inflater pools with ContainerLifeCycle Signed-off-by: Lachlan Roberts --- .../util/compression/CompressionPool.java | 16 ++++- .../api/extensions/ExtensionFactory.java | 58 +++-------------- .../websocket/client/WebSocketClient.java | 1 + .../extensions/WebSocketExtensionFactory.java | 62 ++++++++++++++++++- .../server/WebSocketServerFactory.java | 1 + 5 files changed, 85 insertions(+), 53 deletions(-) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/compression/CompressionPool.java b/jetty-util/src/main/java/org/eclipse/jetty/util/compression/CompressionPool.java index f4108339c51..6582f5d3a90 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/compression/CompressionPool.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/compression/CompressionPool.java @@ -22,7 +22,9 @@ import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.atomic.AtomicInteger; -public abstract class CompressionPool +import org.eclipse.jetty.util.component.AbstractLifeCycle; + +public abstract class CompressionPool extends AbstractLifeCycle { public static final int INFINITE_CAPACITY = -1; @@ -117,4 +119,16 @@ public abstract class CompressionPool } } } + + @Override + public void doStop() + { + T t = _pool.poll(); + while (t != null) + { + end(t); + t = _pool.poll(); + } + _numObjects.set(0); + } } \ No newline at end of file diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionFactory.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionFactory.java index 80ca434db18..eae3dd3fbe6 100644 --- a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionFactory.java +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionFactory.java @@ -18,64 +18,22 @@ package org.eclipse.jetty.websocket.api.extensions; -import java.util.HashMap; -import java.util.Iterator; import java.util.Map; -import java.util.ServiceLoader; import java.util.Set; -public abstract class ExtensionFactory implements Iterable> +public interface ExtensionFactory extends Iterable> { - private ServiceLoader extensionLoader = ServiceLoader.load(Extension.class); - private Map> availableExtensions; + Map> getAvailableExtensions(); - public ExtensionFactory() - { - availableExtensions = new HashMap<>(); - for (Extension ext : extensionLoader) - { - if (ext != null) - { - availableExtensions.put(ext.getName(),ext.getClass()); - } - } - } + Class getExtension(String name); - public Map> getAvailableExtensions() - { - return availableExtensions; - } + Set getExtensionNames(); - public Class getExtension(String name) - { - return availableExtensions.get(name); - } + boolean isAvailable(String name); - public Set getExtensionNames() - { - return availableExtensions.keySet(); - } + Extension newInstance(ExtensionConfig config); - public boolean isAvailable(String name) - { - return availableExtensions.containsKey(name); - } + void register(String name, Class extension); - @Override - public Iterator> iterator() - { - return availableExtensions.values().iterator(); - } - - public abstract Extension newInstance(ExtensionConfig config); - - public void register(String name, Class extension) - { - availableExtensions.put(name,extension); - } - - public void unregister(String name) - { - availableExtensions.remove(name); - } + void unregister(String name); } diff --git a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java index 071079e9050..1e025c53ac2 100644 --- a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java +++ b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java @@ -274,6 +274,7 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont // Support Late Binding of Object Factory (for CDI) this.objectFactorySupplier = () -> scope.getObjectFactory(); this.extensionRegistry = new WebSocketExtensionFactory(this); + addBean(extensionRegistry); this.eventDriverFactory = eventDriverFactory == null ? new EventDriverFactory(this) : eventDriverFactory; this.sessionFactory = sessionFactory == null ? new WebSocketSessionFactory(this) : sessionFactory; diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/WebSocketExtensionFactory.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/WebSocketExtensionFactory.java index cffeeea85fc..43a1355b5ec 100644 --- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/WebSocketExtensionFactory.java +++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/WebSocketExtensionFactory.java @@ -18,9 +18,15 @@ package org.eclipse.jetty.websocket.common.extensions; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.ServiceLoader; +import java.util.Set; import java.util.zip.Deflater; import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.compression.CompressionPool; import org.eclipse.jetty.util.compression.DeflaterPool; import org.eclipse.jetty.util.compression.InflaterPool; @@ -31,16 +37,50 @@ import org.eclipse.jetty.websocket.api.extensions.ExtensionFactory; import org.eclipse.jetty.websocket.common.extensions.compress.CompressExtension; import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; -public class WebSocketExtensionFactory extends ExtensionFactory +public class WebSocketExtensionFactory extends ContainerLifeCycle implements ExtensionFactory { private WebSocketContainerScope container; + private ServiceLoader extensionLoader = ServiceLoader.load(Extension.class); + private Map> availableExtensions; private final InflaterPool inflaterPool = new InflaterPool(CompressionPool.INFINITE_CAPACITY, true); private final DeflaterPool deflaterPool = new DeflaterPool(CompressionPool.INFINITE_CAPACITY, Deflater.DEFAULT_COMPRESSION, true); public WebSocketExtensionFactory(WebSocketContainerScope container) { - super(); + availableExtensions = new HashMap<>(); + for (Extension ext : extensionLoader) + { + if (ext != null) + availableExtensions.put(ext.getName(),ext.getClass()); + } + this.container = container; + addBean(inflaterPool); + addBean(deflaterPool); + } + + @Override + public Map> getAvailableExtensions() + { + return availableExtensions; + } + + @Override + public Class getExtension(String name) + { + return availableExtensions.get(name); + } + + @Override + public Set getExtensionNames() + { + return availableExtensions.keySet(); + } + + @Override + public boolean isAvailable(String name) + { + return availableExtensions.containsKey(name); } @Override @@ -86,4 +126,22 @@ public class WebSocketExtensionFactory extends ExtensionFactory throw new WebSocketException("Cannot instantiate extension: " + extClass,e); } } + + @Override + public void register(String name, Class extension) + { + availableExtensions.put(name,extension); + } + + @Override + public void unregister(String name) + { + availableExtensions.remove(name); + } + + @Override + public Iterator> iterator() + { + return availableExtensions.values().iterator(); + } } diff --git a/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java b/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java index ee86aec9edd..4755b5c3306 100644 --- a/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java +++ b/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java @@ -186,6 +186,7 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc addBean(scheduler); addBean(bufferPool); addBean(sessionTracker); + addBean(extensionFactory); listeners.add(this.sessionTracker); }