All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.bigdata.service.proxy.ClientFuture Maven / Gradle / Ivy

package com.bigdata.service.proxy;

import java.io.IOException;
import java.io.Serializable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;

/**
 * {@link Serializable} class wraps a {@link RemoteFuture} delegating
 * methods through to the {@link Future} on the remote service while
 * masquerading {@link IOException}s so that we can implement the
 * {@link Future} API.
 * 
 * @author Bryan Thompson
 * @version $Id$
 * @param 
 */
public class ClientFuture implements Future, Serializable {
    
    protected static final transient Logger log = Logger
            .getLogger(ClientFuture.class);
    
    /**
     * 
     */
    private static final long serialVersionUID = -910518634373204705L;
    
    private final RemoteFuture proxy;

    /**
     * Set true once we know the Future to be done.
     */
    private volatile transient boolean done = false;

    /**
     * 
     * @param proxy
     *            A proxy for the {@link RemoteFuture}.
     */
    public ClientFuture(final RemoteFuture proxy) {

        if (proxy == null)
            throw new IllegalArgumentException();

        this.proxy = proxy;

    }

    /**
     * Note: I have observed problems where an attempt to cancel a remote future
     * fails when DGC is enabled. The stack trace looks like:
     * 
     * 
     * java.util.concurrent.ExecutionException: java.lang.RuntimeException: java.rmi.NoSuchObjectException: no such object in table
     *         at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:232)
     *         at java.util.concurrent.FutureTask.get(FutureTask.java:91)
     *         at com.bigdata.service.proxy.RemoteFutureImpl.get(RemoteFutureImpl.java:48)
     *         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
     *         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
     *         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
     *         at java.lang.reflect.Method.invoke(Method.java:597)
     *         at net.jini.jeri.BasicInvocationDispatcher.invoke(BasicInvocationDispatcher.java:1126)
     *         at net.jini.jeri.BasicInvocationDispatcher.dispatch(BasicInvocationDispatcher.java:608)
     *         at com.sun.jini.jeri.internal.runtime.ObjectTable$6.run(ObjectTable.java:597)
     *         at net.jini.export.ServerContext.doWithServerContext(ServerContext.java:103)
     *         at com.sun.jini.jeri.internal.runtime.ObjectTable$Target.dispatch0(ObjectTable.java:595)
     *         at com.sun.jini.jeri.internal.runtime.ObjectTable$Target.access$700(ObjectTable.java:212)
     *         at com.sun.jini.jeri.internal.runtime.ObjectTable$5.run(ObjectTable.java:568)
     *         at java.security.AccessController.doPrivileged(Native Method)
     *         at com.sun.jini.jeri.internal.runtime.ObjectTable$Target.dispatch(ObjectTable.java:565)
     *         at com.sun.jini.jeri.internal.runtime.ObjectTable$Target.dispatch(ObjectTable.java:540)
     *         at com.sun.jini.jeri.internal.runtime.ObjectTable$RD.dispatch(ObjectTable.java:778)
     *         at net.jini.jeri.connection.ServerConnectionManager$Dispatcher.dispatch(ServerConnectionManager.java:148)
     *         at com.sun.jini.jeri.internal.mux.MuxServer$2.run(MuxServer.java:244)
     *         at java.security.AccessController.doPrivileged(Native Method)
     *         at com.sun.jini.jeri.internal.mux.MuxServer$1.run(MuxServer.java:241)
     *         at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:136)
     *         at java.lang.Thread.run(Thread.java:619)
     *         at com.sun.jini.jeri.internal.runtime.Util.__________EXCEPTION_RECEIVED_FROM_SERVER__________(Util.java:108)
     *         at com.sun.jini.jeri.internal.runtime.Util.exceptionReceivedFromServer(Util.java:101)
     *         at net.jini.jeri.BasicInvocationHandler.unmarshalThrow(BasicInvocationHandler.java:1303)
     *         at net.jini.jeri.BasicInvocationHandler.invokeRemoteMethodOnce(BasicInvocationHandler.java:832)
     *         at net.jini.jeri.BasicInvocationHandler.invokeRemoteMethod(BasicInvocationHandler.java:659)
     *         at net.jini.jeri.BasicInvocationHandler.invoke(BasicInvocationHandler.java:528)
     *         at $Proxy8.get(Unknown Source)
     *         at com.bigdata.service.proxy.ClientFuture.get(ClientFuture.java:67)
     *         at com.bigdata.relation.rule.eval.pipeline.JoinMasterTask.awaitAll(JoinMasterTask.java:528)
     *         at com.bigdata.relation.rule.eval.pipeline.JoinMasterTask.call(JoinMasterTask.java:378)
     *         at com.bigdata.relation.rule.eval.pipeline.JoinMasterTask.call(JoinMasterTask.java:236)
     *         at com.bigdata.relation.rule.eval.AbstractStepTask.runOne(AbstractStepTask.java:331)
     *         at com.bigdata.relation.rule.eval.MutationTask.call(MutationTask.java:113)
     *         at com.bigdata.relation.rule.eval.MutationTask.call(MutationTask.java:55)
     *         at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
     *         at java.util.concurrent.FutureTask.run(FutureTask.java:138)
     *         at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
     *         at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
     *         at java.lang.Thread.run(Thread.java:619)
     * Caused by: java.lang.RuntimeException: java.rmi.NoSuchObjectException: no such object in table
     *         at com.bigdata.service.proxy.ClientFuture.cancel(ClientFuture.java:48)
     *         at com.bigdata.relation.rule.eval.pipeline.DistributedJoinTask.cancelSinks(DistributedJoinTask.java:956)
     *         at com.bigdata.relation.rule.eval.pipeline.JoinTask.call(JoinTask.java:511)
     *         at com.bigdata.relation.rule.eval.pipeline.JoinTask.call(JoinTask.java:128)
     *         ... 5 more
     * Caused by: java.rmi.NoSuchObjectException: no such object in table
     *         at net.jini.jeri.BasicObjectEndpoint.executeCall(BasicObjectEndpoint.java:420)
     *         at net.jini.jeri.BasicInvocationHandler.invokeRemoteMethodOnce(BasicInvocationHandler.java:806)
     *         at net.jini.jeri.BasicInvocationHandler.invokeRemoteMethod(BasicInvocationHandler.java:659)
     *         at net.jini.jeri.BasicInvocationHandler.invoke(BasicInvocationHandler.java:528)
     *         at $Proxy9.cancel(Unknown Source)
     *         at com.bigdata.service.proxy.ClientFuture.cancel(ClientFuture.java:46)
     *         ... 8 more
     * 
* * This appears to be an RMI/DGC bug where the remote future is somehow * garbage collected even though this class is holding a reference to its * {@link RemoteFuture} proxy. *

* Since the remote future no longer exists we can assume that it is no * longer running. Therefore, I have modified this method to log a warning * and return false when this exception is thrown. *

* Note: I have also seen this problem where the stack trace involves * java.rmi.ConnectException. * * @see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6181943 * @see http://archives.java.sun.com/cgi-bin/wa?A2=ind0509&L=rmi-users&P=617 * @see http://archives.java.sun.com/cgi-bin/wa?A2=ind0512&L=rmi-users&P=3747 * @see http://archives.java.sun.com/cgi-bin/wa?A2=ind0601&L=rmi-users&P=1985 */ public boolean cancel(final boolean mayInterruptIfRunning) { if (done) { /* * The task could not be cancelled (because it is already known to * be done). */ return false; } try { return proxy.cancel(mayInterruptIfRunning); } catch (java.rmi.ConnectException ex) { /* * Log a warning. */ if (log.isEnabledFor(Level.WARN)) { log.warn(ex.getLocalizedMessage()); } /* * Return false since not provably cancelled in response to this * request. */ return false; } catch (java.rmi.NoSuchObjectException ex) { /* * Log a warning. */ if (log.isEnabledFor(Level.WARN)) { log.warn(ex.getLocalizedMessage()); } /* * Return false since not provably cancelled in response to this * request. * * Note: if the object is gone, then a likely explanation is that * the Future completed and has been finalized. */ return false; } catch (IOException e) { throw new RuntimeException(e); } } public T get() throws InterruptedException, ExecutionException { try { final T t = proxy.get(); done = true; return t; } catch (IOException e) { throw new RuntimeException(e); } } public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { try { final T t = proxy.get(timeout, unit); done = true; return t; } catch (IOException e) { throw new RuntimeException(e); } } public boolean isCancelled() { try { final boolean t = proxy.isCancelled(); if (t) { // If cancelled, then also done. done = true; } return t; } catch (IOException e) { throw new RuntimeException(e); } } public boolean isDone() { try { if (done) return done; done = proxy.isDone(); return done; } catch (IOException e) { throw new RuntimeException(e); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy