Work-around RestEasy executor hang bug.
@@ -26,10 +26,14 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.URI;
+import java.net.URISyntaxException;
import java.util.Map;
+import java.util.Objects;
import java.util.concurrent.CompletionException;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
@@ -38,19 +42,50 @@ import java.util.function.Function;
*/
public class RegistryClient {
- private RegistryClient() {
+ // TODO -- more options?
+ public static class Builder {
+ private URI baseUrl;
+ private ExecutorService executor;
+
+ public Builder() {
}
- // TODO -- more options?
- public static RegistryService create(String baseUrl) throws Exception {
+ public Builder setBaseUrl(String baseUrl) {
+ try {
+ this.baseUrl = new URI(Objects.requireNonNull(baseUrl));
+ return this;
+ } catch (URISyntaxException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ public Builder setBaseUrl(URI baseUrl) {
+ this.baseUrl = Objects.requireNonNull(baseUrl);
+ return this;
+ }
+
+ public Builder setExecutor(ExecutorService executor) {
+ this.executor = executor; // can be null
+ return this;
+ }
+
+ public RegistryService build() {
return (RegistryService) Proxy.newProxyInstance(
RegistryClient.class.getClassLoader(),
new Class[]{RegistryService.class},
- new ServiceProxy(new URI(baseUrl))
+ new ServiceProxy(this)
);
}
+ }
+
+ private RegistryClient() {
+ }
+
+ public static RegistryService create(String baseUrl) {
+ return new Builder().setBaseUrl(baseUrl).build();
+ }
- public static RegistryService cached(String baseUrl) throws Exception {
+ public static RegistryService cached(String baseUrl) {
return cached(create(baseUrl));
}
@@ -80,10 +115,15 @@ public class RegistryClient {
private final AtomicBoolean closed = new AtomicBoolean();
private final URI baseUri;
+ private final ExecutorService executor;
+
+ private final boolean shutdownExecutor;
private final RegistryFilter filter;
- public ServiceProxy(URI baseUri) {
- this.baseUri = baseUri;
+ private ServiceProxy(Builder builder) {
+ this.baseUri = builder.baseUrl;
+ this.shutdownExecutor = (builder.executor == null);
+ this.executor = (shutdownExecutor ? Executors.newFixedThreadPool(10) : builder.executor);
this.filter = new RegistryFilter();
}
@@ -100,6 +140,10 @@ public class RegistryClient {
} catch (IOException ignore) {
}
});
+ // work-around a bug in RestEasy builder
+ if (shutdownExecutor) {
+ executor.shutdown();
+ }
}
} else if ("reset".equals(methodName)) {
// do nothing
@@ -115,6 +159,7 @@ public class RegistryClient {
Object target = targets.compute(targetClass, (aClass, o) -> RestClientBuilder.newBuilder()
.baseUri(baseUri)
.register(filter)
+ .executorService(executor)
.build(targetClass));
Object result = method.invoke(target, args);
if (result instanceof CompletionStage) {
