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

com.bigdata.ha.AbstractMessageTask Maven / Gradle / Ivy

package com.bigdata.ha;

import java.io.IOException;
import java.rmi.Remote;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;

import com.bigdata.ha.msg.IHAMessage;
import com.bigdata.quorum.ServiceLookup;

/**
 * Helper class submits the RMI for a PREPARE, COMMIT, or ABORT message. This is
 * used to execute the different requests in parallel on a local executor
 * service.
 * 
 * @author Bryan Thompson
 */
abstract class AbstractMessageTask
        implements Callable {

    private final ServiceLookup serviceLookup;
    private final UUID serviceId;
    protected final M msg;

    public AbstractMessageTask(final ServiceLookup serviceLookup,
            final UUID serviceId, final M msg) {

        this.serviceLookup = serviceLookup;

        this.serviceId = serviceId;

        this.msg = msg;

    }

    @Override
    final public T call() throws Exception {

        /*
         * Note: This code MAY be interrupted at any point if the Future for the
         * task is cancelled. If it is interrupted during the RMI, then the
         * expectation is that the NIO will be interrupted in a timely manner
         * throwing back some sort of IOException indicating the asynchronous
         * close of the IO channel or cancel of the RMI.
         */

        // Resolve proxy for remote service.
        final S service = serviceLookup.getService(serviceId);

        // RMI.
        final Future ft = doRMI(service);

        try {

            /*
             * Await the inner Future for the RMI.
             * 
             * Note: In fact, this is a ThickFuture so it is already done by the
             * time the RMI returns.
             */

            return ft.get();

        } finally {

            ft.cancel(true/* mayInterruptIfRunning */);

        }

    }

    /**
     * Invoke the specific RMI using the message supplied to the constructor.
     * 
     * @param service
     *            The service (resolved from the service {@link UUID} supplied
     *            to the constructor).
     * 
     * @return The result of submitting that RMI to the remote service.
     * 
     * @throws IOException
     *             if there is a problem with the RMI.
     */
    abstract protected Future doRMI(final S service) throws IOException;

}