Example usage for com.google.common.util.concurrent SettableFuture setFuture

List of usage examples for com.google.common.util.concurrent SettableFuture setFuture

Introduction

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

Prototype

@Beta
    @Override
    public boolean setFuture(ListenableFuture<? extends V> future) 

Source Link

Usage

From source file:com.facebook.buck.parser.PipelineNodeCache.java

/**
 * Helper for de-duping jobs against the cache.
 *
 * @param jobSupplier a supplier to use to create the actual job.
 * @return future describing the job. It can either be an immediate future (result cache hit),
 *         ongoing job (job cache hit) or a new job (miss).
 *//*from   w w  w . ja  v  a2 s  .  c  om*/
protected final ListenableFuture<T> getJobWithCacheLookup(final Cell cell, final K key,
        JobSupplier<T> jobSupplier) throws BuildTargetException {
    Optional<T> cacheLookupResult = cache.lookupComputedNode(cell, key);
    if (cacheLookupResult.isPresent()) {
        return Futures.immediateFuture(cacheLookupResult.get());
    }

    ListenableFuture<T> speculativeCacheLookupResult = jobsCache.get(key);
    if (speculativeCacheLookupResult != null) {
        return speculativeCacheLookupResult;
    }

    // We use a SettableFuture to resolve any races between threads that are trying to create the
    // job for the given key. The SettableFuture is cheap to throw away in case we didn't "win" and
    // can be easily "connected" to a future that actually does work in case we did.
    SettableFuture<T> resultFutureCandidate = SettableFuture.create();
    ListenableFuture<T> resultFutureInCache = jobsCache.putIfAbsent(key, resultFutureCandidate);
    if (resultFutureInCache != null) {
        // Another thread succeeded in putting the new value into the cache.
        return resultFutureInCache;
    }
    // Ok, "our" candidate future went into the jobsCache, schedule the job and 'chain' the result
    // to the SettableFuture, so that anyone else waiting on it will get the same result.
    final SettableFuture<T> resultFuture = resultFutureCandidate;
    try {
        ListenableFuture<T> nodeJob = Futures.transformAsync(jobSupplier.get(),
                input -> Futures.immediateFuture(cache.putComputedNodeIfNotPresent(cell, key, input)));
        resultFuture.setFuture(nodeJob);
    } catch (Throwable t) {
        resultFuture.setException(t);
        throw t;
    }
    return resultFuture;
}