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

com.lafaspot.icap.client.session.IcapFuture Maven / Gradle / Ivy

There is a newer version: 0.0.13
Show newest version
/**
 *
 */
package com.lafaspot.icap.client.session;

import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;

import javax.annotation.Nonnull;

import com.lafaspot.icap.client.IcapResult;

/**
 * @author kraman
 *
 */
public class IcapFuture implements Future {

    /** Holds the current session. */
    private final AtomicReference sessionRef = new AtomicReference();
    /** Is this future task done? */
    private final AtomicBoolean isDone = new AtomicBoolean(false);
    /** Holds the failure cause. */
    private final AtomicReference causeRef = new AtomicReference();
    /** Used to synchronize threads. */
    private final Object lock = new Object();
    /** holds the result object. */
    private final AtomicReference resultRef = new AtomicReference();
    /** Wait interval when the user calls get(). */
    private static final int GET_WAIT_INTERVAL_MILLIS = 1000;

    /**
     * Constructor.
     *
     * @param session the IcapSession object
     * */
    public IcapFuture(@Nonnull final IcapSession session) {
        this.sessionRef.set(session);
    }

    /**
     * Cancel the Future task. TODO:
     *
     * @param mayInterruptIfRunning should the task be cancelled if running?
     * @return true if cancel was successful
     */
    @Override
    public boolean cancel(final boolean mayInterruptIfRunning) {
        // TODO
        return false;
    }

    /**
     * Is this Future cancelled? TODO: return return true if cancelled
     *
     * @return true if Future was cancelled
     */
    @Override
    public boolean isCancelled() {
        // TODO
        return false;
    }

    /**
     * Is the future task complete?
     *
     * @return true if task is complete
     */
    @Override
    public boolean isDone() {
        return isDone.get();
    }

    /**
     * Invoked when the worker has completed its processing.
     *
     * @param result the result to be set
     */
    protected void done(@Nonnull final IcapResult result) {
        synchronized (lock) {
            if (!isDone.get()) {
                IcapSession session = sessionRef.get();
                if (sessionRef.compareAndSet(session, null)) {
                    resultRef.set(result);
                    isDone.set(true);
                }
            }
            lock.notify();
        }
    }

    /**
     * Invoked when the worker throws an exception.
     *
     * @param cause the exception that caused execution to fail
     */
    protected void done(final Exception cause) {
        synchronized (lock) {
            if (!isDone.get()) {
                IcapSession session = sessionRef.get();
                if (sessionRef.compareAndSet(session, null)) {
                    causeRef.set(cause);
                    isDone.set(true);
                }
            }
            lock.notify();
        }
    }

    /**
     * Synchronously get the result, will hold the thread until the task is complete.
     *
     * @return the result object
     * @throws InterruptedException on failure
     * @throws ExecutionException on failure
     */
    @Override
    public IcapResult get() throws InterruptedException, ExecutionException {
        synchronized (lock) {
            while (!isDone.get()) {
                lock.wait(GET_WAIT_INTERVAL_MILLIS);
            }
            lock.notify();
        }
        if (causeRef.get() != null) {
            throw new ExecutionException(causeRef.get());
        } else if (isCancelled()) {
            throw new CancellationException();
        } else {
            return resultRef.get();
        }
    }

    /**
     * Synchronously get the result, will hold the thread until the task is complete or timeout is passed.
     *
     * @return the result object
     * @param timeout time to wait before giving up
     * @param unit unit value for timeout
     * @throws InterruptedException on failure
     * @throws ExecutionException on failure
     * @throws TimeoutException when timeout has expired
     */
    @Override
    public IcapResult get(final long timeout, @Nonnull final TimeUnit unit) throws InterruptedException, ExecutionException,
            TimeoutException {
        synchronized (lock) {
            if (!isDone.get()) {
                lock.wait(unit.toMillis(timeout));
            }
            lock.notify();
        }
        if (isDone.get()) {
            if (causeRef.get() != null) {
                throw new ExecutionException(causeRef.get());
            } else if (isCancelled()) {
                throw new CancellationException();
            } else {
                return resultRef.get();
            }
        } else {
            throw new TimeoutException("Timeout reached.");
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy