package org.gcube.common.clients.delegates; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.gcube.common.clients.Call; import org.gcube.common.clients.config.ProxyConfig; import org.gcube.common.security.providers.SecretManagerProvider; import org.gcube.common.security.secrets.Secret; /** * A {@link ProxyDelegate} that delivers the outcome of {@link Call}s asynchronously, either through polling or * notifications. *
* The delegates use {@link ExecutorService}s to make calls in separate threads. If required, clients may provide their own
* {@link ExecutorService}s at the point of call submission.
*
* @author Fabio Simeoni
*
* @param the type of service stubs
*/
public class AsyncProxyDelegate implements ProxyDelegate {
// we try to cope with demand within holding on to threads that may never be used
private final static ExecutorService service = Executors.newCachedThreadPool();
// quits the default service when JVM does
static {
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
service.shutdown();
}
});
}
// the inner synchronous delegate
private final ProxyDelegate inner;
/**
* Creates an instance with a (synchronous) {@link ProxyDelegate}
*
* @param delegate the delegate
*/
public AsyncProxyDelegate(ProxyDelegate delegate) {
this.inner = delegate;
}
@Override
public call) throws Exception {
return inner.make(call);
}
@Override
public ProxyConfig, S> config() {
return inner.config();
}
/**
* Makes a {@link Call} to a service endpoint asynchronously, returning a {@link Future} that clients can use to
* poll for and obtain the call outcome, or to cancel the call (assuming that the call is designed for cancellation
* or has not been made yet).
*
* @param call the {@link Call} to be made asynchronously
* @return the {@link Future} of the {@link Call} outcome
*
* @param call) throws RejectedExecutionException {
return makeAsync(call, service);
}
/**
* Makes a {@link Call} to a service endpoint asynchronously, returning a {@link Future} that clients can use to
* poll for and obtain the call outcome, or to cancel the call (assuming that the call is designed for cancellation
* or has not been made yet).
*
* @param call the {@link Call} to be executed asynchronously
* @param service a {@link ExecutorService} to which the {@link Call} should be submitted for execution
*
* @return the {@link Future} of the {@link Call} outcome
*
* @param call, ExecutorService service) throws RejectedExecutionException {
final Secret secret = SecretManagerProvider.get();
// create task from call
Callable call, final Callback call, final Callback