Issue #300 - manage deflater/inflater pools with ContainerLifeCycle

Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
This commit is contained in:
Lachlan Roberts 2019-06-18 12:31:25 +10:00
parent f05d6cf9ad
commit 30dc103a12
5 changed files with 85 additions and 53 deletions

View File

@ -22,7 +22,9 @@ import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
public abstract class CompressionPool<T>
import org.eclipse.jetty.util.component.AbstractLifeCycle;
public abstract class CompressionPool<T> extends AbstractLifeCycle
{
public static final int INFINITE_CAPACITY = -1;
@ -117,4 +119,16 @@ public abstract class CompressionPool<T>
}
}
}
@Override
public void doStop()
{
T t = _pool.poll();
while (t != null)
{
end(t);
t = _pool.poll();
}
_numObjects.set(0);
}
}

View File

@ -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<Class<? extends Extension>>
public interface ExtensionFactory extends Iterable<Class<? extends Extension>>
{
private ServiceLoader<Extension> extensionLoader = ServiceLoader.load(Extension.class);
private Map<String, Class<? extends Extension>> availableExtensions;
Map<String, Class<? extends Extension>> getAvailableExtensions();
public ExtensionFactory()
{
availableExtensions = new HashMap<>();
for (Extension ext : extensionLoader)
{
if (ext != null)
{
availableExtensions.put(ext.getName(),ext.getClass());
}
}
}
Class<? extends Extension> getExtension(String name);
public Map<String, Class<? extends Extension>> getAvailableExtensions()
{
return availableExtensions;
}
Set<String> getExtensionNames();
public Class<? extends Extension> getExtension(String name)
{
return availableExtensions.get(name);
}
boolean isAvailable(String name);
public Set<String> getExtensionNames()
{
return availableExtensions.keySet();
}
Extension newInstance(ExtensionConfig config);
public boolean isAvailable(String name)
{
return availableExtensions.containsKey(name);
}
void register(String name, Class<? extends Extension> extension);
@Override
public Iterator<Class<? extends Extension>> iterator()
{
return availableExtensions.values().iterator();
}
public abstract Extension newInstance(ExtensionConfig config);
public void register(String name, Class<? extends Extension> extension)
{
availableExtensions.put(name,extension);
}
public void unregister(String name)
{
availableExtensions.remove(name);
}
void unregister(String name);
}

View File

@ -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;

View File

@ -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<Extension> extensionLoader = ServiceLoader.load(Extension.class);
private Map<String, Class<? extends Extension>> 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<String, Class<? extends Extension>> getAvailableExtensions()
{
return availableExtensions;
}
@Override
public Class<? extends Extension> getExtension(String name)
{
return availableExtensions.get(name);
}
@Override
public Set<String> 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<? extends Extension> extension)
{
availableExtensions.put(name,extension);
}
@Override
public void unregister(String name)
{
availableExtensions.remove(name);
}
@Override
public Iterator<Class<? extends Extension>> iterator()
{
return availableExtensions.values().iterator();
}
}

View File

@ -186,6 +186,7 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
addBean(scheduler);
addBean(bufferPool);
addBean(sessionTracker);
addBean(extensionFactory);
listeners.add(this.sessionTracker);
}