List of usage examples for com.google.common.util.concurrent SettableFuture setFuture
@Beta @Override public boolean setFuture(ListenableFuture<? extends V> future)
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; }