Skip to content

Commit

Permalink
[RESTEASY-2174][RESTEASY-2175] ResteasyProviderFactory refactoring / …
Browse files Browse the repository at this point in the history
…optimization (#1879)

* TCCL-based cache of initial client ResteasyProviderFactory

* Get rid of exceptionMapper in RPF (use sortedExceptionMappers)

* Reduce number of objects created for each new RPF instance

* RPF refactoring to split the class into some smaller / more readable ones and to allow reducing memory allocation in case the RPF is needed only on client or server side

* Minor cleanup of MediaTypeMap

* Adding MediaType cache

* Replacing Class#newInstance method usage in RPF (deprecated in JDK9)

* Some reasonable sizing of ConcurrentHashMaps in RPF (based on the number of existing implementations in RESTEasy for the various keys)

* Adding MediaType -> String (reverse) map

* Simple bench test to measure performance of RPF usage on client side
  • Loading branch information
asoldano committed Mar 1, 2019
1 parent ef7bac3 commit ea17ab7
Show file tree
Hide file tree
Showing 41 changed files with 2,129 additions and 1,150 deletions.
Expand Up @@ -57,7 +57,10 @@ public ClientConfiguration(final ClientConfiguration parent)

public void setProperties(Map<String, Object> newProps)
{
providerFactory.setProperties(newProps);
if (newProps != null && !newProps.isEmpty())
{
providerFactory.setProperties(newProps);
}
}

protected ResteasyProviderFactory getProviderFactory()
Expand Down
Expand Up @@ -2,7 +2,9 @@

import javax.ws.rs.RuntimeType;

import org.jboss.resteasy.core.ResteasyProviderFactoryImpl;
import org.jboss.resteasy.core.providerfactory.ClientHelper;
import org.jboss.resteasy.core.providerfactory.NOOPServerHelper;
import org.jboss.resteasy.core.providerfactory.ResteasyProviderFactoryImpl;
import org.jboss.resteasy.spi.ResteasyProviderFactory;

/**
Expand All @@ -26,4 +28,11 @@ public RuntimeType getRuntimeType()
{
return RuntimeType.CLIENT;
}

@Override
protected void initializeUtils()
{
clientHelper = new ClientHelper(this);
serverHelper = NOOPServerHelper.INSTANCE;
}
}
Expand Up @@ -9,12 +9,13 @@
import org.jboss.resteasy.client.jaxrs.engines.ClientHttpEngineBuilder43;
import org.jboss.resteasy.client.jaxrs.i18n.LogMessages;
import org.jboss.resteasy.client.jaxrs.i18n.Messages;
import org.jboss.resteasy.core.ResteasyProviderFactoryImpl;
import org.jboss.resteasy.core.providerfactory.ResteasyProviderFactoryImpl;
import org.jboss.resteasy.plugins.providers.RegisterBuiltin;
import org.jboss.resteasy.spi.ResteasyProviderFactory;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.ws.rs.RuntimeType;
import javax.ws.rs.core.Configuration;

import java.security.KeyStore;
Expand Down Expand Up @@ -316,8 +317,7 @@ public ResteasyProviderFactory getProviderFactory()
if (providerFactory == null)
{
// create a new one
providerFactory = new LocalResteasyProviderFactory(ResteasyProviderFactory.newInstance());
RegisterBuiltin.register(providerFactory);
providerFactory = new LocalResteasyProviderFactory(RegisterBuiltin.getClientInitializedResteasyProviderFactory(Thread.currentThread().getContextClassLoader()));

if (ResteasyProviderFactory.peekInstance() != null)
{
Expand Down Expand Up @@ -451,7 +451,13 @@ public ResteasyClientBuilderImpl register(Object component, Map<Class<?>, Intege
@Override
public ResteasyClientBuilderImpl withConfig(Configuration config)
{
providerFactory = new LocalResteasyProviderFactory(new ResteasyProviderFactoryImpl());
providerFactory = new ResteasyProviderFactoryImpl() {
@Override
public RuntimeType getRuntimeType()
{
return RuntimeType.CLIENT;
}
};
providerFactory.setProperties(config.getProperties());
for (Class clazz : config.getClasses())
{
Expand Down
Expand Up @@ -133,9 +133,9 @@ public static ResteasyProviderFactory newInstance()
try
{
return (ResteasyProviderFactory) Thread.currentThread().getContextClassLoader()
.loadClass("org.jboss.resteasy.core.ResteasyProviderFactoryImpl").newInstance();
.loadClass("org.jboss.resteasy.core.providerfactory.ResteasyProviderFactoryImpl").getDeclaredConstructor().newInstance();
}
catch (InstantiationException | IllegalAccessException | ClassNotFoundException e)
catch (Exception e)
{
throw new RuntimeException(e);
}
Expand Down
@@ -1,5 +1,6 @@
package org.jboss.resteasy.core;

import org.jboss.resteasy.core.providerfactory.ResteasyProviderFactoryImpl;
import org.jboss.resteasy.resteasy_jaxrs.i18n.LogMessages;
import org.jboss.resteasy.spi.ApplicationException;
import org.jboss.resteasy.spi.Failure;
Expand Down Expand Up @@ -55,7 +56,7 @@ protected Response executeExactExceptionMapper(Throwable exception, RESTEasyTrac
if (logger == null)
logger = RESTEasyTracingLogger.empty();

ExceptionMapper mapper = providerFactory.getExceptionMappers().get(exception.getClass());
ExceptionMapper mapper = providerFactory.getExceptionMapperForClass(exception.getClass());
if (mapper == null) return null;
mapperExecuted = true;
long timestamp = logger.timestamp("EXCEPTION_MAPPING");
Expand All @@ -75,7 +76,7 @@ protected Response executeExceptionMapperForClass(Throwable exception, Class cla
{
if (logger == null)
logger = RESTEasyTracingLogger.empty();
ExceptionMapper mapper = providerFactory.getExceptionMappers().get(clazz);
ExceptionMapper mapper = providerFactory.getExceptionMapperForClass(clazz);
if (mapper == null) return null;
mapperExecuted = true;
long timestamp = logger.timestamp("EXCEPTION_MAPPING");
Expand Down Expand Up @@ -123,7 +124,7 @@ protected Response executeExceptionMapper(Throwable exception, RESTEasyTracingLo
Class causeClass = exception.getClass();
while (mapper == null) {
if (causeClass == null) break;
mapper = providerFactory.getExceptionMappers().get(causeClass);
mapper = providerFactory.getExceptionMapperForClass(causeClass);
if (mapper == null) causeClass = causeClass.getSuperclass();
}

Expand Down
Expand Up @@ -42,6 +42,8 @@
@SuppressWarnings({"unchecked", "rawtypes"})
public class InjectorFactoryImpl implements InjectorFactory
{
public static final InjectorFactoryImpl INSTANCE = new InjectorFactoryImpl();

@Override
public ConstructorInjector createConstructor(Constructor constructor, ResteasyProviderFactory providerFactory)
{
Expand Down
Expand Up @@ -115,14 +115,14 @@ public int compareTo(Entry<?> entry)
}
}

private static Pattern COMPOSITE_PATTERN = Pattern.compile("([^\\+]+)\\+(.+)");
private static final Pattern COMPOSITE_PATTERN = Pattern.compile("([^\\+]+)\\+(.+)");

// Composite subtypes are of the pattern *+subtype i.e. *+xml, *+json
public static Pattern COMPOSITE_SUBTYPE_WILDCARD_PATTERN = Pattern.compile("\\*\\+(.+)");
public static final Pattern COMPOSITE_SUBTYPE_WILDCARD_PATTERN = Pattern.compile("\\*\\+(.+)");


// This composite is subtype+* i.e. atom+* rss+*
public static Pattern WILD_SUBTYPE_COMPOSITE_PATTERN = Pattern.compile("([^\\+]+)\\+\\*");
public static final Pattern WILD_SUBTYPE_COMPOSITE_PATTERN = Pattern.compile("([^\\+]+)\\+\\*");

private static class SubtypeMap<T>
{
Expand Down Expand Up @@ -252,14 +252,7 @@ public MediaTypeMap<T> clone()
return clone;
}

public Map<CachedMediaTypeAndClass, List<T>> getClassCache()
{
return classCache;
}



public static class CachedMediaTypeAndClass
private static class CachedMediaTypeAndClass
{
// we need a weak reference because of possible hot deployment
// Although, these reference should get cleared up with any add() invocation
Expand Down
Expand Up @@ -2,6 +2,9 @@

import org.jboss.resteasy.annotations.Stream;
import org.jboss.resteasy.core.interception.jaxrs.PostMatchContainerRequestContext;
import org.jboss.resteasy.core.providerfactory.NOOPClientHelper;
import org.jboss.resteasy.core.providerfactory.ResteasyProviderFactoryImpl;
import org.jboss.resteasy.core.providerfactory.ServerHelper;
import org.jboss.resteasy.core.registry.SegmentNode;
import org.jboss.resteasy.plugins.server.resourcefactory.SingletonResource;
import org.jboss.resteasy.resteasy_jaxrs.i18n.LogMessages;
Expand Down Expand Up @@ -108,7 +111,14 @@ public Class<?> getResourceClass()
}
};

this.resourceMethodProviderFactory = new ResteasyProviderFactoryImpl(providerFactory);
this.resourceMethodProviderFactory = new ResteasyProviderFactoryImpl(providerFactory) {
@Override
protected void initializeUtils()
{
clientHelper = NOOPClientHelper.INSTANCE;
serverHelper = new ServerHelper(this);
}
};
for (DynamicFeature feature : providerFactory.getServerDynamicFeatures())
{
feature.configure(resourceInfo, new DynamicFeatureContextDelegate(resourceMethodProviderFactory));
Expand Down Expand Up @@ -224,7 +234,14 @@ public void cleanup()

public void registryUpdated(JaxrsInterceptorRegistry registry)
{
this.resourceMethodProviderFactory = new ResteasyProviderFactoryImpl(parentProviderFactory);
this.resourceMethodProviderFactory = new ResteasyProviderFactoryImpl(parentProviderFactory) {
@Override
protected void initializeUtils()
{
clientHelper = NOOPClientHelper.INSTANCE;
serverHelper = new ServerHelper(this);
}
};
for (DynamicFeature feature : parentProviderFactory.getServerDynamicFeatures())
{
feature.configure(resourceInfo, new FeatureContextDelegate(resourceMethodProviderFactory));
Expand Down
Expand Up @@ -29,6 +29,7 @@
import javax.ws.rs.ext.ReaderInterceptor;
import javax.ws.rs.ext.WriterInterceptor;

import org.jboss.resteasy.core.providerfactory.ResteasyProviderFactoryImpl;
import org.jboss.resteasy.resteasy_jaxrs.i18n.LogMessages;
import org.jboss.resteasy.spi.AsyncResponseProvider;
import org.jboss.resteasy.spi.AsyncStreamProvider;
Expand Down Expand Up @@ -504,12 +505,6 @@ public <T extends Throwable> ExceptionMapper<T> getExceptionMapper(Class<T> type
return getDelegate().getExceptionMapper(type);
}

@Override
public Map<Class<?>, ExceptionMapper> getExceptionMappers()
{
return ((ResteasyProviderFactoryImpl)getDelegate()).getExceptionMappers();
}

@Override
public <T> AsyncResponseProvider<T> getAsyncResponseProvider(Class<T> type)
{
Expand Down
@@ -1,6 +1,6 @@
package org.jboss.resteasy.core.interception.jaxrs;

import org.jboss.resteasy.core.ResteasyProviderFactoryImpl;
import org.jboss.resteasy.core.providerfactory.ResteasyProviderFactoryImpl;
import org.jboss.resteasy.resteasy_jaxrs.i18n.Messages;
import org.jboss.resteasy.spi.HttpRequest;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
Expand Down
@@ -1,7 +1,7 @@
package org.jboss.resteasy.core.interception.jaxrs;

import org.jboss.resteasy.core.NoMessageBodyWriterFoundFailure;
import org.jboss.resteasy.core.ResteasyProviderFactoryImpl;
import org.jboss.resteasy.core.providerfactory.ResteasyProviderFactoryImpl;
import org.jboss.resteasy.spi.HttpRequest;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.jboss.resteasy.tracing.RESTEasyTracingLogger;
Expand Down

0 comments on commit ea17ab7

Please sign in to comment.