diff options
author | slewis | 2018-03-15 16:00:06 +0000 |
---|---|---|
committer | slewis | 2018-03-15 16:00:06 +0000 |
commit | 04409504a18579c8fe90b18a8d9bb72bc84cdddb (patch) | |
tree | 7d4a0b68a9b4df2b85313c8d3763b00dc35e299c /framework | |
parent | eca50a8929df30b12b3dfc826e59a73fbe5f07a2 (diff) | |
download | org.eclipse.ecf-04409504a18579c8fe90b18a8d9bb72bc84cdddb.tar.gz org.eclipse.ecf-04409504a18579c8fe90b18a8d9bb72bc84cdddb.tar.xz org.eclipse.ecf-04409504a18579c8fe90b18a8d9bb72bc84cdddb.zip |
Additional fixes for bug
https://bugs.eclipse.org/bugs/show_bug.cgi?id=532205
Added API to AbstractRSAClientService to simplify the creation of
providers.
Change-Id: I57d69eeaf81de2230eb6ad163c6199f5a780a341
Diffstat (limited to 'framework')
2 files changed, 142 insertions, 15 deletions
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 01437f489..9b92aee46 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 @@ -703,17 +703,18 @@ public abstract class AbstractRemoteService extends AbstractAsyncProxyRemoteServ /** * @since 8.13 */ - public Object submitCallable(Callable<Object> callable, long timeout) throws ECFException { - Future<Object> f = getFutureExecutorService(null).submit(callable); - try { - return f.get(timeout, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - throw new ECFException("submitCallable interrupted", e); //$NON-NLS-1$ - } catch (ExecutionException e) { - throw new ECFException("submitCallable interrupted", e.getCause()); //$NON-NLS-1$ - } catch (TimeoutException e) { - throw new ECFException("submitCallable timed out", e); //$NON-NLS-1$ - } + public Future<Object> callAsync(IRemoteCall call, Callable<Object> callable) { + return getFutureExecutorService(call).submit(callable); + } + + /** + * @throws TimeoutException + * @throws ExecutionException + * @throws InterruptedException + * @since 8.13 + */ + public Object callSync(IRemoteCall call, Callable<Object> callable) throws InterruptedException, ExecutionException, TimeoutException { + return callAsync(call, callable).get(call.getTimeout(), TimeUnit.MILLISECONDS); } /** @@ -728,4 +729,80 @@ public abstract class AbstractRemoteService extends AbstractAsyncProxyRemoteServ iFutureExecutor = null; } } + + /** + * @since 8.13 + */ + protected Future<Object> callAsyncWithTimeout(final IRemoteCall call, final Callable<Object> callable) { + return getFutureExecutorService(call).submit(new Callable<Object>() { + public Object call() throws Exception { + try { + return getFutureExecutorService(call).submit(callable).get(call.getTimeout(), TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + throw new InterruptedException("Interrupted calling remote service method=" + call.getMethod()); //$NON-NLS-1$ + } catch (ExecutionException e) { + throw new InvocationTargetException(e.getCause(), "Exception calling remote service method=" + call.getMethod()); //$NON-NLS-1$ + } catch (TimeoutException e) { + throw new TimeoutException("Timeout calling remote service method=" + call.getMethod() + " timeout=" + call.getTimeout()); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + }); + } + + /** + * @since 8.13 + */ + protected IRemoteCallCompleteEvent createRCCESuccess(final Object result) { + return createRCCE(result, null); + } + + /** + * @since 8.13 + */ + protected IRemoteCallCompleteEvent createRCCEFailure(final Throwable e) { + return createRCCE(null, e); + } + + /** + * @since 8.13 + */ + protected IRemoteCallCompleteEvent createRCCE(final Object result, final Throwable e) { + return new IRemoteCallCompleteEvent() { + public long getRequestId() { + return 0; + } + + public Object getResponse() { + return result; + } + + public boolean hadException() { + return (e != null); + } + + public Throwable getException() { + return e; + } + }; + } + + /** + * @since 8.13 + */ + protected void callAsyncWithTimeout(final IRemoteCall call, final Callable<IRemoteCallCompleteEvent> callable, final IRemoteCallListener callback) { + getFutureExecutorService(call).submit(new Runnable() { + public void run() { + try { + callback.handleEvent(getFutureExecutorService(call).submit(callable).get(call.getTimeout(), TimeUnit.MILLISECONDS)); + } catch (InterruptedException e) { + callback.handleEvent(createRCCE(null, new InterruptedException("Interrupted calling remote service method=" + call.getMethod()))); //$NON-NLS-1$ + } catch (ExecutionException e) { + callback.handleEvent(createRCCE(null, new InvocationTargetException(e.getCause(), "Exception calling remote service method=" + call.getMethod()))); //$NON-NLS-1$ + } catch (TimeoutException e) { + callback.handleEvent(createRCCE(null, new TimeoutException("Timeout calling remote service method=" + call.getMethod() + " timeout=" + call.getTimeout()))); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + }); + } + } diff --git a/framework/bundles/org.eclipse.ecf.remoteservice/src/org/eclipse/ecf/remoteservice/client/AbstractRSAClientService.java b/framework/bundles/org.eclipse.ecf.remoteservice/src/org/eclipse/ecf/remoteservice/client/AbstractRSAClientService.java index a7bd70f82..aa6c4371d 100644 --- a/framework/bundles/org.eclipse.ecf.remoteservice/src/org/eclipse/ecf/remoteservice/client/AbstractRSAClientService.java +++ b/framework/bundles/org.eclipse.ecf.remoteservice/src/org/eclipse/ecf/remoteservice/client/AbstractRSAClientService.java @@ -10,9 +10,10 @@ package org.eclipse.ecf.remoteservice.client; import java.lang.reflect.Method; +import java.util.concurrent.*; import org.eclipse.ecf.core.util.ECFException; -import org.eclipse.ecf.remoteservice.IRemoteCall; -import org.eclipse.ecf.remoteservice.RemoteCall; +import org.eclipse.ecf.remoteservice.*; +import org.eclipse.ecf.remoteservice.events.IRemoteCallCompleteEvent; import org.osgi.framework.ServiceException; /** @@ -67,7 +68,9 @@ public abstract class AbstractRSAClientService extends AbstractClientService { * @return Object. Should return a non-null instance of {@link org.eclipse.equinox.concurrent.future.IFuture}, {@link java.util.concurrent.Future}, or {@link java.util.concurrent.CompletableFuture} * @throws ECFException if async cannot be invoked */ - protected abstract Object invokeAsync(RSARemoteCall remoteCall) throws ECFException; + protected Object invokeAsync(RSARemoteCall remoteCall) throws ECFException { + return callFuture(remoteCall, remoteCall.getReflectMethod().getReturnType()); + } /** * Invoke a remote call synchronously. This method should block until a value may be returned, or the remote @@ -77,7 +80,23 @@ public abstract class AbstractRSAClientService extends AbstractClientService { * @return the result (of appropriate type) * @throws ECFException if some exception occurred during invocation */ - protected abstract Object invokeSync(RSARemoteCall remoteCall) throws ECFException; + protected Object invokeSync(RSARemoteCall remoteCall) throws ECFException { + if (remoteCall.getClass().isAssignableFrom(RSARemoteCall.class)) { + Callable<Object> c = createSyncCallable(remoteCall); + if (c == null) + throw new ECFException("invokeSync failed on method=" + remoteCall.getMethod(), new NullPointerException("createSyncCallable() must not return null. It's necessary for distribution provider to override createSyncCallable.")); //$NON-NLS-1$ //$NON-NLS-2$ + try { + return callSync(remoteCall, c); + } catch (InterruptedException e) { + throw new ECFException("invokeSync interrupted on method=" + remoteCall.getMethod(), e); //$NON-NLS-1$ + } catch (ExecutionException e) { + throw new ECFException("invokeSync exception on method=" + remoteCall.getMethod(), e.getCause()); //$NON-NLS-1$ + } catch (TimeoutException e) { + throw new ECFException("invokeSync timeout on method=" + remoteCall.getMethod(), e); //$NON-NLS-1$ + } + } + return super.invokeSync(remoteCall); + } protected RSARemoteCall createRemoteCall(Object proxy, Method method, String methodName, Object[] parameters, long timeout) { return new RSARemoteCall(proxy, method, methodName, parameters, timeout); @@ -113,4 +132,35 @@ public abstract class AbstractRSAClientService extends AbstractClientService { throw new ServiceException("Service exception on remote service proxy rsid=" + getRemoteServiceID(), ServiceException.REMOTE, t); //$NON-NLS-1$ } } + + @Override + protected ExecutorService getFutureExecutorService(IRemoteCall call) { + return super.getFutureExecutorService(call); + } + + @Override + protected void callAsync(IRemoteCall call, IRemoteCallable callable, IRemoteCallListener listener) { + if (call.getClass().isAssignableFrom(RSARemoteCall.class)) { + Callable<IRemoteCallCompleteEvent> c = createAsyncCallable((RSARemoteCall) call); + if (c == null) + throw new NullPointerException("createAsyncCallable returns null. Distribution provider must override createAsyncCallable"); //$NON-NLS-1$ + callAsyncWithTimeout(call, c, listener); + } + super.callAsync(call, callable, listener); + } + + /** + * @since 8.13 + */ + protected Callable<IRemoteCallCompleteEvent> createAsyncCallable(final RSARemoteCall call) { + return null; + } + + /** + * @since 8.13 + */ + protected Callable<Object> createSyncCallable(final RSARemoteCall call) { + return null; + } + } |