Async invocation performance improvements
Despite having an asynchronous option, the default CXF client is purely synchronous. Furthermore, the more advanced CXF clients are still synchronous if a custom SSLContext is used. Finally, even when asynchronous, all of the filters, interceptors, readers and writers are run on the calling thread. Performance is better with a simpler implementation which makes use of the PromiseFactory#submit() method and a SyncInvoker.
Signed-off-by: Tim Ward <timothyjward@apache.org>
diff --git a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/cxf/jaxrs/client/PromiseRxInvokerImpl.java b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/cxf/jaxrs/client/PromiseRxInvokerImpl.java
index 7ad5dc3..db0e8df 100644
--- a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/cxf/jaxrs/client/PromiseRxInvokerImpl.java
+++ b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/cxf/jaxrs/client/PromiseRxInvokerImpl.java
@@ -19,51 +19,19 @@
import javax.ws.rs.HttpMethod;
import javax.ws.rs.client.Entity;
-import javax.ws.rs.client.InvocationCallback;
+import javax.ws.rs.client.SyncInvoker;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.Response;
-import org.apache.cxf.jaxrs.client.WebClient;
import org.osgi.service.jaxrs.client.PromiseRxInvoker;
-import org.osgi.util.promise.Deferred;
import org.osgi.util.promise.Promise;
import org.osgi.util.promise.PromiseFactory;
-import java.lang.reflect.Method;
-import java.lang.reflect.Type;
-
class PromiseRxInvokerImpl implements PromiseRxInvoker {
- private final Method _doInvokeAsyncMethod;
-
- private static final class DeferredHandler<R> implements InvocationCallback<R> {
- private final Deferred<R> deferred;
-
- private DeferredHandler(Deferred<R> deferred) {
- this.deferred = deferred;
- }
-
- @Override
- public void completed(R response) {
- deferred.resolve(response);
- }
-
- @Override
- public void failed(Throwable throwable) {
- deferred.fail(throwable);
- }
- }
public PromiseRxInvokerImpl(
- WebClient webClient, PromiseFactory promiseFactory) {
- _webClient = webClient;
- try {
- _doInvokeAsyncMethod = WebClient.class.getDeclaredMethod(
- "doInvokeAsync",
- String.class, Object.class, Class.class, Type.class, Class.class, Type.class, InvocationCallback.class);
- } catch (NoSuchMethodException nsme) {
- throw new RuntimeException(nsme);
- }
- _doInvokeAsyncMethod.setAccessible(true);
+ SyncInvoker syncInvoker, PromiseFactory promiseFactory) {
+ _syncInvoker = syncInvoker;
_promiseFactory = promiseFactory;
}
@@ -104,49 +72,18 @@
@Override
public <R> Promise<R> method(String s, Class<R> responseType) {
- Deferred<R> deferred = _promiseFactory.deferred();
-
- try {
- _doInvokeAsyncMethod.invoke(
- _webClient, s, null, null, null, responseType, responseType,
- new DeferredHandler<R>(deferred));
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
-
- return deferred.getPromise();
+ return _promiseFactory.submit(() -> _syncInvoker.method(s, responseType));
}
@Override
public <R> Promise<R> method(String s, Entity<?> entity, Class<R> responseType) {
- Deferred<R> deferred = _promiseFactory.deferred();
-
- try {
- _doInvokeAsyncMethod.invoke(
- _webClient, s, entity, null, null, responseType, responseType,
- new DeferredHandler<R>(deferred));
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
-
- return deferred.getPromise();
+ return _promiseFactory.submit(() -> _syncInvoker.method(s, entity, responseType));
}
@Override
public <R> Promise<R> method(
String s, Entity<?> entity, GenericType<R> genericType) {
-
- Deferred<R> deferred = _promiseFactory.deferred();
-
- try {
- _doInvokeAsyncMethod.invoke(
- _webClient, s, entity, null, null, genericType.getRawType(),
- genericType.getType(), new DeferredHandler<R>(deferred));
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
-
- return deferred.getPromise();
+ return _promiseFactory.submit(() -> _syncInvoker.method(s, entity, genericType));
}
@Override
@@ -156,17 +93,7 @@
@Override
public <R> Promise<R> method(String s, GenericType<R> genericType) {
- Deferred<R> deferred = _promiseFactory.deferred();
-
- try {
- _doInvokeAsyncMethod.invoke(
- _webClient, s, null, null, null, genericType.getRawType(),
- genericType.getType(), new DeferredHandler<R>(deferred));
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
-
- return deferred.getPromise();
+ return _promiseFactory.submit(() -> _syncInvoker.method(s, genericType));
}
@Override
@@ -235,5 +162,5 @@
}
private final PromiseFactory _promiseFactory;
- private final WebClient _webClient;
+ private final SyncInvoker _syncInvoker;
}
diff --git a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/cxf/jaxrs/client/PromiseRxInvokerProviderImpl.java b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/cxf/jaxrs/client/PromiseRxInvokerProviderImpl.java
index 46e7ade..919ec9f 100644
--- a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/cxf/jaxrs/client/PromiseRxInvokerProviderImpl.java
+++ b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/cxf/jaxrs/client/PromiseRxInvokerProviderImpl.java
@@ -22,7 +22,6 @@
import javax.ws.rs.client.RxInvokerProvider;
import javax.ws.rs.client.SyncInvoker;
-import org.apache.cxf.jaxrs.client.SyncInvokerImpl;
import org.osgi.service.jaxrs.client.PromiseRxInvoker;
import org.osgi.util.promise.PromiseFactory;
@@ -48,7 +47,7 @@
PromiseFactory.inlineExecutor());
}
- return new PromiseRxInvokerImpl(((SyncInvokerImpl) syncInvoker).getWebClient(), promiseFactory);
+ return new PromiseRxInvokerImpl(syncInvoker, promiseFactory);
}
}