diff options
author | Scott Lewis | 2013-10-25 09:18:42 +0000 |
---|---|---|
committer | Markus Alexander Kuppe | 2013-10-25 14:23:22 +0000 |
commit | f62333bb5ce7ba11b19f04d260f06b22ead43faf (patch) | |
tree | df2520b9a33218c4a10946e08a0259c0aa80066c | |
parent | ad1ec7941c4cdacb806bd8bbbebeb05cd723c275 (diff) | |
download | org.eclipse.ecf-f62333bb5ce7ba11b19f04d260f06b22ead43faf.tar.gz org.eclipse.ecf-f62333bb5ce7ba11b19f04d260f06b22ead43faf.tar.xz org.eclipse.ecf-f62333bb5ce7ba11b19f04d260f06b22ead43faf.zip |
NEW - bug 420290: Asynchronous Remote Services may support
java.util.concurrent.Future
https://bugs.eclipse.org/bugs/show_bug.cgi?id=420290
Signed-off-by: Markus Alexander Kuppe <bugs.eclipse.org@lemmster.de>
Change-Id: I903caca3f27fba87014ea30fc074fc4c8e7f0c4f
2 files changed, 72 insertions, 7 deletions
diff --git a/framework/bundles/org.eclipse.ecf.remoteservice/META-INF/MANIFEST.MF b/framework/bundles/org.eclipse.ecf.remoteservice/META-INF/MANIFEST.MF index b1094e95f..f994ce35b 100644 --- a/framework/bundles/org.eclipse.ecf.remoteservice/META-INF/MANIFEST.MF +++ b/framework/bundles/org.eclipse.ecf.remoteservice/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %plugin.name Bundle-SymbolicName: org.eclipse.ecf.remoteservice -Bundle-Version: 8.1.0.qualifier +Bundle-Version: 8.2.0.qualifier Bundle-Activator: org.eclipse.ecf.internal.remoteservice.Activator Bundle-Vendor: %plugin.provider Bundle-Localization: plugin diff --git a/framework/bundles/org.eclipse.ecf.remoteservice/src/org/eclipse/ecf/remoteservice/AbstractRemoteService.java b/framework/bundles/org.eclipse.ecf.remoteservice/src/org/eclipse/ecf/remoteservice/AbstractRemoteService.java index 723517130..d78e14cb8 100644 --- a/framework/bundles/org.eclipse.ecf.remoteservice/src/org/eclipse/ecf/remoteservice/AbstractRemoteService.java +++ b/framework/bundles/org.eclipse.ecf.remoteservice/src/org/eclipse/ecf/remoteservice/AbstractRemoteService.java @@ -11,6 +11,7 @@ package org.eclipse.ecf.remoteservice; import java.lang.reflect.*; import java.util.*; +import java.util.concurrent.*; import org.eclipse.core.runtime.*; import org.eclipse.ecf.core.jobs.JobsExecutor; import org.eclipse.ecf.core.util.ECFException; @@ -27,6 +28,7 @@ import org.osgi.util.tracker.ServiceTracker; * * @since 4.1 */ +//@ProviderType public abstract class AbstractRemoteService implements IRemoteService, InvocationHandler { protected static final Object[] EMPTY_ARGS = new Object[0]; @@ -307,6 +309,13 @@ public abstract class AbstractRemoteService implements IRemoteService, Invocatio protected class AsyncArgs { private IRemoteCallListener listener; private Object[] args; + private boolean isIFuture; + + public AsyncArgs(Object[] originalArgs, boolean isIFuture) { + this.listener = null; + this.args = originalArgs; + this.isIFuture = isIFuture; + } public AsyncArgs(IRemoteCallListener listener, Object[] originalArgs) { this.listener = listener; @@ -325,6 +334,13 @@ public abstract class AbstractRemoteService implements IRemoteService, Invocatio public Object[] getArgs() { return args; } + + /** + * @since 8.2 + */ + public boolean isIFuture() { + return isIFuture; + } } /** @@ -347,21 +363,70 @@ public abstract class AbstractRemoteService implements IRemoteService, Invocatio return DEFAULT_TIMEOUT; } }; - if (listener == null) - return callAsync(call); + // IFuture or Future will have listener == null + if (listener == null) { + if (asyncArgs.isIFuture()) + return callAsync(call); + return callJREAsync(call); + } + return callAsyncWithResult(call, listener); + } + + /** + * @since 8.2 + */ + protected Object callAsyncWithResult(IRemoteCall call, IRemoteCallListener listener) { callAsync(call, listener); return null; } /** + * @since 8.2 + */ + protected Future callJREAsync(final IRemoteCall call) { + ExecutorService executorService = getFutureExecutorService(); + if (executorService == null) + throw new ServiceException("Future executor service is null. Cannot call method=" + call.getMethod()); //$NON-NLS-1$ + return executorService.submit(new Callable() { + public Object call() throws Exception { + return callSync(call); + } + }); + } + + /** + * @since 8.2 + */ + protected int futureExecutorServiceMaxThreads = 10; + + /** + * @since 8.2 + */ + protected ExecutorService futureExecutorService; + + /** + * @since 8.2 + */ + protected ExecutorService getFutureExecutorService() { + synchronized (this) { + if (futureExecutorService == null) + futureExecutorService = Executors.newFixedThreadPool(futureExecutorServiceMaxThreads); + } + return futureExecutorService; + } + + /** * @since 3.3 */ protected AsyncArgs getAsyncArgs(Method method, Object[] args) { IRemoteCallListener listener = null; Class returnType = method.getReturnType(); - // If the return type is declared to be *anything* except an IFuture, then - // we are expecting the last argument to be an IRemoteCallListener - if (!returnType.equals(IFuture.class)) { + // If the return type is of type java.util.concurrent.Future, then we return + if (returnType.equals(Future.class)) { + return new AsyncArgs(args, false); + } else if (returnType.equals(IFuture.class)) { + return new AsyncArgs(args, true); + } else { // If the provided args do *not* include an IRemoteCallListener then we have a problem if (args == null || args.length == 0) throw new IllegalArgumentException("Async calls must include a IRemoteCallListener instance as the last argument"); //$NON-NLS-1$ @@ -379,8 +444,8 @@ public abstract class AbstractRemoteService implements IRemoteService, Invocatio // If the last are is not an instance of IRemoteCallListener then there is a problem if (listener == null) throw new IllegalArgumentException("Last argument must be an instance of IRemoteCallListener"); //$NON-NLS-1$ + return new AsyncArgs(listener, args); } - return new AsyncArgs(listener, args); } /** |