下面列出了com.google.common.util.concurrent.ListenableFuture#isDone ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private static String canDebug(
DeviceFutures deviceFutures, AndroidFacet facet, String moduleName) {
// If we are debugging on a device, then the app needs to be debuggable
for (ListenableFuture<IDevice> future : deviceFutures.get()) {
if (!future.isDone()) {
// this is an emulator, and we assume that all emulators are debuggable
continue;
}
IDevice device = Futures.getUnchecked(future);
if (!LaunchUtils.canDebugAppOnDevice(facet, device)) {
return AndroidBundle.message(
"android.cannot.debug.noDebugPermissions", moduleName, device.getName());
}
}
return null;
}
/**
* Refreshes the value associated with {@code key}, unless another thread is already doing so.
* Returns the newly refreshed value associated with {@code key} if it was refreshed inline, or
* {@code null} if another thread is performing the refresh or if an error occurs during
* refresh.
*/
@Nullable
V refresh(K key, int hash, CacheLoader<? super K, V> loader, boolean checkTime) {
final LoadingValueReference<K, V> loadingValueReference = insertLoadingValueReference(key, hash, checkTime);
if (loadingValueReference == null) {
return null;
}
ListenableFuture<V> result = loadAsync(key, hash, loadingValueReference, loader);
if (result.isDone()) {
try {
return Uninterruptibles.getUninterruptibly(result);
} catch (Throwable t) {
// don't let refresh exceptions propagate; error was already logged
}
}
return null;
}
@Test(expectedExceptions = ExecutionException.class)
public void shouldAssertAsyncHttpStatusCodeContinuallyEqualsFails() throws Exception {
stopServer();
ListeningExecutorService listeningExecutor = MoreExecutors.listeningDecorator(executor);
final ListenableFuture<?> future =
HttpAsserts.assertAsyncHttpStatusCodeContinuallyEquals(listeningExecutor, testUri("/missing"), 200);
startAfter(DELAY_FOR_SERVER_TO_SETTLE.add(Duration.seconds(1)));
Time.sleep(DELAY_FOR_SERVER_TO_SETTLE);
if (future.isDone()) {
Object result = future.get(); // should throw exception
LOG.warn("Should have failed, instead gave "+result+" (accessing "+server+")");
} else {
LOG.warn("Future should have been done");
}
future.cancel(true);
}
/**
* Refreshes the value associated with {@code key}, unless another thread is already doing so.
* Returns the newly refreshed value associated with {@code key} if it was refreshed inline, or
* {@code null} if another thread is performing the refresh or if an error occurs during
* refresh.
*/
@Nullable
V refresh(K key, int hash, CacheLoader<? super K, V> loader, boolean checkTime) {
final LoadingValueReference<K, V> loadingValueReference =
insertLoadingValueReference(key, hash, checkTime);
if (loadingValueReference == null) {
return null;
}
ListenableFuture<V> result = loadAsync(key, hash, loadingValueReference, loader);
if (result.isDone()) {
try {
return Uninterruptibles.getUninterruptibly(result);
} catch (Throwable t) {
// don't let refresh exceptions propagate; error was already logged
}
}
return null;
}
/**
* Queries the kind of the current target pattern, possibly asynchronously, in the case where
* there's only a single target.
*
* @param asyncCallback if the kind is updated asynchronously, this will be run after the kind is
* updated. If it's updated synchronously, this will not be run.
*/
void updateTargetKindAsync(@Nullable Runnable asyncCallback) {
ImmutableList<TargetExpression> targets = parseTargets(targetPatterns);
if (targets.size() != 1 || !(targets.get(0) instanceof Label)) {
// TODO(brendandouglas): any reason to support multiple targets here?
updateTargetKind(null);
return;
}
Label label = (Label) targets.get(0);
ListenableFuture<TargetInfo> future = TargetFinder.findTargetInfoFuture(getProject(), label);
if (future.isDone()) {
updateTargetKindFromSingleTarget(FuturesUtil.getIgnoringErrors(future));
} else {
updateTargetKindFromSingleTarget(null);
future.addListener(
() -> {
updateTargetKindFromSingleTarget(FuturesUtil.getIgnoringErrors(future));
if (asyncCallback != null) {
asyncCallback.run();
}
},
MoreExecutors.directExecutor());
}
}
private ListenableFuture<?> loadSplits()
throws IOException
{
Iterator<InternalHiveSplit> splits = fileIterators.poll();
if (splits == null) {
HivePartitionMetadata partition = partitions.poll();
if (partition == null) {
return COMPLETED_FUTURE;
}
return loadPartition(partition);
}
while (splits.hasNext() && !stopped) {
ListenableFuture<?> future = hiveSplitSource.addToQueue(splits.next());
if (!future.isDone()) {
fileIterators.addFirst(splits);
return future;
}
}
// No need to put the iterator back, since it's either empty or we've stopped
return COMPLETED_FUTURE;
}
@Override
public void run() {
// If either of these reads return null then we must be after a
// successful cancel or another call to this method.
TimeoutFuture<V> timeoutFuture = timeoutFutureRef;
if (timeoutFuture == null) {
return;
}
ListenableFuture<V> delegate = timeoutFuture.delegateRef;
if (delegate == null) {
return;
}
/*
* If we're about to complete the TimeoutFuture, we want to release our
* reference to it. Otherwise, we'll pin it (and its result) in memory
* until the timeout task is GCed. (The need to clear our reference to
* the TimeoutFuture is the reason we use a *static* nested class with
* a manual reference back to the "containing" class.)
*
* This has the nice-ish side effect of limiting reentrancy: run() calls
* timeoutFuture.setException() calls run(). That reentrancy would
* already be harmless, since timeoutFuture can be set (and delegate
* cancelled) only once. (And "set only once" is important for other
* reasons: run() can still be invoked concurrently in different threads,
* even with the above null checks.)
*/
timeoutFutureRef = null;
if (delegate.isDone()) {
timeoutFuture.setFuture(delegate);
} else {
try {
timeoutFuture.setException(
new TimeoutException("Future timed out: " + delegate));
} finally {
delegate.cancel(true);
}
}
}
/**
* 校验ResponseFuture
*
* @Author yuanzhonglin
* @since 2019/4/8
*/
private static <RespT> void judgeResponseFuture(ListenableFuture<RespT> responseFuture
, ThreadlessExecutor executor){
while (!responseFuture.isDone()) {
try {
executor.waitAndDrain();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw Status.CANCELLED
.withDescription("Call was interrupted")
.withCause(e)
.asRuntimeException();
}
}
}
private void addFuture(final ListenableFuture<Void> future, final Action action)
{
if(action != null)
{
if(future.isDone())
{
action.postCommit();
}
else
{
_futureRecorder.recordFuture(future, action);
}
}
}
/**
* Iterates through all {@link SourceToTargetFinder}s, returning the first immediately available,
* non-empty result.
*/
static Collection<TargetInfo> findTargetsForSourceFile(
Project project, File sourceFile, Optional<RuleType> ruleType) {
ListenableFuture<Collection<TargetInfo>> future =
findTargetInfoFuture(project, sourceFile, ruleType);
if (future.isDone()) {
Collection<TargetInfo> targets = FuturesUtil.getIgnoringErrors(future);
if (targets != null && !targets.isEmpty()) {
return targets;
}
}
return ImmutableList.of();
}
@SuppressWarnings("unchecked")
public String render(Renderer renderer, DataList data) throws InterruptedException, IOException {
TestContentChannel contentChannel = new TestContentChannel();
Execution execution = Execution.createRoot(new NoopProcessor(), 0, null);
final ContentChannelOutputStream stream = new ContentChannelOutputStream(contentChannel);
ListenableFuture result = renderer.render(stream, new Response(data), execution, null);
int waitCounter = 1000;
while (!result.isDone()) {
Thread.sleep(60);
--waitCounter;
if (waitCounter < 0) {
throw new IllegalStateException();
}
}
stream.close();
contentChannel.close(null);
String str = "";
for (ByteBuffer buf : contentChannel.getBuffers()) {
str += Utf8.toString(buf);
}
return str;
}
private void waitForSufficientBalance(Coin amount) {
// Not enough money in the wallet.
Coin amountPlusFee = amount.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE);
// ESTIMATED because we don't really need to wait for confirmation.
ListenableFuture<Coin> balanceFuture = appKit.wallet().getBalanceFuture(amountPlusFee, Wallet.BalanceType.ESTIMATED);
if (!balanceFuture.isDone()) {
System.out.println("Please send " + amountPlusFee.toFriendlyString() +
" to " + myKey.toAddress(params));
Futures.getUnchecked(balanceFuture);
}
}
private void assertDriversProgress(Predicate<OperatorContext> reason)
{
do {
assertFalse(isOperatorBlocked(drivers, reason));
boolean progress = false;
for (Driver driver : drivers) {
ListenableFuture<?> blocked = driver.process();
progress = progress | blocked.isDone();
}
// query should not block
assertTrue(progress);
}
while (!drivers.stream().allMatch(Driver::isFinished));
}
/**
* Asynchronous hello
*
* @param user user name
* @param depth depth of nested calls, {@literal 0} for simple calls, use positive value for nesting
* @return an hello statement
*/
public final Future<String> saysHelloAsync(String user, int depth) {
Req request = buildRequest(user, depth);
ListenableFuture<Rep> future = executeAsync(request);
return new Future<>() {
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
return future.cancel(mayInterruptIfRunning);
}
@Override
public boolean isCancelled() {
return future.isCancelled();
}
@Override
public boolean isDone() {
return future.isDone();
}
@Override
public String get() throws InterruptedException, ExecutionException {
// TODO : check if something is thrown when there is a server error
return getResponseMessage(future.get());
}
@Override
public String get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
// TODO : check if something is thrown when there is a server error
return getResponseMessage(future.get(timeout, unit));
}
};
}
@Override
public ListenableFuture<?> processFor(Duration duration)
{
calls.incrementAndGet();
long callStart = System.nanoTime();
startNanos.compareAndSet(-1, callStart);
lastReadyTime.compareAndSet(-1, callStart);
waitNanos.addAndGet(callStart - lastReadyTime.get());
boolean done = process();
long callEnd = System.nanoTime();
completedProcessNanos.addAndGet(callEnd - callStart);
if (done) {
doneNanos.compareAndSet(-1, callEnd);
if (!isKilled()) {
task.splitComplete(this);
}
return immediateFuture(null);
}
ListenableFuture<?> processResult = getProcessResult();
if (processResult.isDone()) {
setSplitReady();
}
return processResult;
}
/**
* Finds a test rule associated with a given {@link PsiElement}. Must be called from within a read
* action.
*/
@Nullable
static ListenableFuture<TargetInfo> targetFutureForPsiElement(
@Nullable PsiElement element, @Nullable TestSize testSize) {
if (element == null) {
return null;
}
PsiFile psiFile = element.getContainingFile();
if (psiFile == null) {
return null;
}
VirtualFile vf = psiFile.getVirtualFile();
File file = vf != null ? new File(vf.getPath()) : null;
if (file == null) {
return null;
}
Project project = element.getProject();
ListenableFuture<Collection<TargetInfo>> targets =
SourceToTargetFinder.findTargetInfoFuture(project, file, Optional.of(RuleType.TEST));
if (targets.isDone() && FuturesUtil.getIgnoringErrors(targets) == null) {
return null;
}
Executor executor =
ApplicationManager.getApplication().isUnitTestMode()
? MoreExecutors.directExecutor()
: PooledThreadExecutor.INSTANCE;
return Futures.transform(
targets,
list ->
list == null
? null
: TestTargetHeuristic.chooseTestTargetForSourceFile(
project, psiFile, file, list, testSize),
executor);
}
@Test(timeout = 5000)
public void test_void_future_from_list_concurrent() throws Exception {
final ImmutableList.Builder<ListenableFuture<Void>> builder = ImmutableList.builder();
final CountDownLatch latch = new CountDownLatch(1);
for (int i = 0; i < 100; i++) {
final SettableFuture<Void> future = SettableFuture.create();
builder.add(future);
new Thread(new Runnable() {
@Override
public void run() {
try {
latch.await();
future.set(null);
} catch (final InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
final ListenableFuture<Void> resultFuture = FutureUtils.voidFutureFromList(builder.build());
latch.countDown();
while (!resultFuture.isDone()) {
Thread.sleep(10);
}
}
@Override
public ListenableFuture<?> isBlocked()
{
ListenableFuture<?> blocked = outputBuffer.isFull();
return blocked.isDone() ? NOT_BLOCKED : blocked;
}
private synchronized void sendUpdate()
{
TaskStatus taskStatus = getTaskStatus();
// don't update if the task hasn't been started yet or if it is already finished
if (!needsUpdate.get() || taskStatus.getState().isDone()) {
return;
}
// if there is a request already running, wait for it to complete
if (this.currentRequest != null && !this.currentRequest.isDone()) {
return;
}
// if throttled due to error, asynchronously wait for timeout and try again
ListenableFuture<?> errorRateLimit = updateErrorTracker.acquireRequestPermit();
if (!errorRateLimit.isDone()) {
errorRateLimit.addListener(this::sendUpdate, executor);
return;
}
List<TaskSource> sources = getSources();
Optional<PlanFragment> fragment = sendPlan.get() ? Optional.of(planFragment) : Optional.empty();
TaskUpdateRequest updateRequest = new TaskUpdateRequest(
session.toSessionRepresentation(),
session.getIdentity().getExtraCredentials(),
fragment,
sources,
outputBuffers.get(),
totalPartitions);
byte[] taskUpdateRequestJson = taskUpdateRequestCodec.toJsonBytes(updateRequest);
if (fragment.isPresent()) {
stats.updateWithPlanBytes(taskUpdateRequestJson.length);
}
HttpUriBuilder uriBuilder = getHttpUriBuilder(taskStatus);
Request request = preparePost()
.setUri(uriBuilder.build())
.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.JSON_UTF_8.toString())
.setBodyGenerator(createStaticBodyGenerator(taskUpdateRequestJson))
.build();
updateErrorTracker.startRequest();
ListenableFuture<JsonResponse<TaskInfo>> future = httpClient.executeAsync(request, createFullJsonResponseHandler(taskInfoCodec));
currentRequest = future;
currentRequestStartNanos = System.nanoTime();
// The needsUpdate flag needs to be set to false BEFORE adding the Future callback since callback might change the flag value
// and does so without grabbing the instance lock.
needsUpdate.set(false);
Futures.addCallback(future, new SimpleHttpResponseHandler<>(new UpdateResponseHandler(sources), request.getUri(), stats), executor);
}
private static boolean futureEmpty(@Nullable ListenableFuture<?> future) {
return future == null
|| future.isCancelled()
|| (future.isDone() && FuturesUtil.getIgnoringErrors(future) == null);
}