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

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

Introduction

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

Prototype

@Override
public boolean set(V newValue) 

Source Link

Document

Sets the value of this future.

Usage

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

@Override
public final <V> V remove(Serializable key) {
    Preconditions.checkNotNull(key, "Key");
    final Queue<ValueFuture<Object>> futures = computations.get(key);

    if (futures.isEmpty()) {
        log.trace("Removing key '{}' from underlying cache", key);
        // no running computation, the easy part
        return this.<V>doRemove(key);
    } else {/*w  w  w.j a  v  a2  s . c o m*/
        log.trace("Forcing all running computations for key '{}' to return null", key);
        while (true) {
            // get and remove in one shot
            final ValueFuture<Object> future = futures.poll();
            if (future == null) {
                // no running computation left
                // weak values should take care of empty queue
                break;
            } else if (future.isDone()) {
                log.trace("{} finished during remove", future);
            } else {
                // return null to callers waiting on Future#get()
                future.set(null);
            }
        }
        // make sure the underlying cache removes any pre-computed value
        return this.<V>doRemove(key);
    }
}

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

@Override
public V remove(Object key) {
    Preconditions.checkNotNull(key, "Key");

    final Queue<ValueFuture<V>> futures = computations.get(key);

    if (futures.isEmpty()) {
        LOG.trace("Removing key '{}' from underlying cache", key);
        // no running computation, the easy part
        return region.remove(key);
    } else {/*from   w w w .j  av  a2s . c om*/
        LOG.trace("Forcing all running computations for key '{}' to return null", key);
        while (true) {
            // get and remove in one shot
            final ValueFuture<V> future = futures.poll();
            if (future == null) {
                // no running computation left
                // weak values should take care of empty queue
                break;
            } else if (future.isDone()) {
                LOG.trace("{} finished during remove", future);
            } else {
                // return null to callers waiting on Future#get()
                future.set(null);
            }
        }
        // make sure the underlying cache removes any pre-computed value
        return region.remove(key);
    }
}

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.  j  a v  a2 s.  co  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  w  ww.j a va  2 s . co  m*/

    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);
    }

}