Example usage for com.google.common.util.concurrent ValueFuture setException

List of usage examples for com.google.common.util.concurrent ValueFuture setException

Introduction

In this page you can find the example usage for com.google.common.util.concurrent ValueFuture setException.

Prototype

@Override
public boolean setException(Throwable t) 

Source Link

Document

Sets the future to having failed with the given exception.

Usage

From source file:de.cosmocode.palava.cache.AbstractComputingCacheService.java

@Override
public final <V> V computeAndStore(Serializable key, Callable<? extends V> callable, CacheExpiration expiration)
        throws CancellationException, ExecutionException {

    Preconditions.checkNotNull(key, "Key");
    Preconditions.checkNotNull(callable, "Callable");
    Preconditions.checkNotNull(expiration, "Expiration");

    final Collection<ValueFuture<Object>> futures = computations.get(key);
    final ValueFuture<Object> future = ValueFuture.create();

    // it's important to do this asap, to allow other callers
    // to wait on read instead of starting the same computation
    futures.add(future);/*from   w  w w . ja va  2 s .  c  o m*/

    try {
        log.trace("Computing value for key '{}' using {}", key, callable);
        final V value = callable.call();

        if (future.isCancelled()) {
            log.warn("{} has been cancelled", future);
        } else if (future.isDone()) {
            log.trace("Another computation was faster and already computed a value for key '{}'", key);
        } else {
            log.trace("Computed value '{}' for key '{}'", value, key);
            future.set(value);
            for (ValueFuture<Object> other : futures) {
                if (other == future) {
                    // every computation after this is newer
                    break;
                } else if (other.isDone()) {
                    log.trace("Skipping finished computation: {}", other);
                    continue;
                } else {
                    // make older and still running computations use my computed value
                    log.trace("Setting faster computed value '{}' on {}", value, other);
                    other.set(value);
                }
            }
            log.trace("Storing '{}' to '{}' in underlying store", key, value);
            doStore(key, value, expiration);
        }

        final V returned = this.<V>cast(future.get());
        if (returned == null) {
            log.trace("Key '{}' has been removed during computation, returning value '{}'", key, value);
            return value;
        } else {
            log.trace("Returning value '{}' for key '{}'", returned, key);
            return returned;
        }
    } catch (ExecutionException e) {
        log.warn("Exception during {}.call()", callable);
        future.setException(e.getCause());
        throw e;
        /* CHECKSTYLE:OFF */
    } catch (Exception e) {
        /* CHECKSTYLE:ON */
        log.warn("Exception during {}.call()", callable);
        future.setException(e);
        throw new ExecutionException(e);
    } finally {
        futures.remove(future);
    }
}

From source file:de.cosmocode.palava.cache.DefaultComputingCacheRegion.java

@Override
public V computeAndPut(K key, Callable<? extends V> computation, CacheExpiration expiration)
        throws ExecutionException {

    Preconditions.checkNotNull(key, "Key");
    Preconditions.checkNotNull(computation, "Computation");
    Preconditions.checkNotNull(expiration, "Expiration");

    final Collection<ValueFuture<V>> futures = computations.get(key);
    final ValueFuture<V> future = ValueFuture.create();

    // it's important to do this asap, to allow other callers
    // to wait on read instead of starting the same computation
    futures.add(future);/*from  ww  w .ja va  2 s  .  c om*/

    try {
        LOG.trace("Computing value for key '{}' using {}", key, computation);
        final V value = computation.call();

        if (future.isCancelled()) {
            LOG.warn("{} has been cancelled", future);
        } else if (future.isDone()) {
            LOG.trace("Another computation was faster and already computed a value for key '{}'", key);
        } else {
            LOG.trace("Computed value '{}' for key '{}'", value, key);
            future.set(value);
            for (ValueFuture<V> other : futures) {
                if (other == future) {
                    // every computation after this is newer
                    break;
                } else if (other.isDone()) {
                    LOG.trace("Skipping finished computation: {}", other);
                    continue;
                } else {
                    // make older and still running computations use my
                    // computed value
                    LOG.trace("Setting faster computed value '{}' on {}", value, other);
                    other.set(value);
                }
            }
            LOG.trace("Storing '{}' to '{}' in underlying store", key, value);
            region.put(key, value, expiration);
        }

        final V returned = future.get();
        if (returned == null) {
            LOG.trace("Key '{}' has been removed during computation, returning computed value '{}'", key,
                    value);
            return value;
        } else {
            LOG.trace("Returning value '{}' for key '{}'", returned, key);
            return returned;
        }
    } catch (ExecutionException e) {
        LOG.warn("Exception during {}.call()", computation);
        future.setException(e.getCause());
        throw e;
        /* CHECKSTYLE:OFF */
    } catch (Exception e) {
        /* CHECKSTYLE:ON */
        LOG.warn("Exception during {}.call()", computation);
        future.setException(e);
        throw new ExecutionException(e);
    } finally {
        futures.remove(future);
    }

}