1 /* 2 * Copyright 2022 Google LLC 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.google.android.libraries.mobiledatadownload.tracing; 17 18 import com.google.common.base.Function; 19 import com.google.common.util.concurrent.AsyncCallable; 20 import com.google.common.util.concurrent.AsyncFunction; 21 import com.google.common.util.concurrent.FutureCallback; 22 import com.google.common.util.concurrent.Futures; 23 import com.google.common.util.concurrent.Futures.FutureCombiner; 24 import com.google.common.util.concurrent.ListenableFuture; 25 import java.util.concurrent.Callable; 26 import java.util.concurrent.Executor; 27 import java.util.concurrent.ScheduledExecutorService; 28 import java.util.concurrent.TimeUnit; 29 import org.checkerframework.checker.nullness.qual.Nullable; 30 31 /** Wrapper around {@link Futures}. */ 32 public final class PropagatedFutures { 33 PropagatedFutures()34 private PropagatedFutures() {} 35 36 public static <I extends @Nullable Object, O extends @Nullable Object> transformAsync( ListenableFuture<I> input, AsyncFunction<? super I, ? extends O> function, Executor executor)37 ListenableFuture<O> transformAsync( 38 ListenableFuture<I> input, 39 AsyncFunction<? super I, ? extends O> function, 40 Executor executor) { 41 return Futures.transformAsync(input, function, executor); 42 } 43 44 public static <I extends @Nullable Object, O extends @Nullable Object> transform( ListenableFuture<I> input, Function<? super I, ? extends O> function, Executor executor)45 ListenableFuture<O> transform( 46 ListenableFuture<I> input, Function<? super I, ? extends O> function, Executor executor) { 47 return Futures.transform(input, function, executor); 48 } 49 addCallback( ListenableFuture<V> future, FutureCallback<? super V> callback, Executor executor)50 public static <V extends @Nullable Object> void addCallback( 51 ListenableFuture<V> future, FutureCallback<? super V> callback, Executor executor) { 52 Futures.addCallback(future, callback, executor); 53 } 54 catching( ListenableFuture<? extends V> input, Class<X> exceptionType, Function<? super X, ? extends V> fallback, Executor executor)55 public static <V extends @Nullable Object, X extends Throwable> ListenableFuture<V> catching( 56 ListenableFuture<? extends V> input, 57 Class<X> exceptionType, 58 Function<? super X, ? extends V> fallback, 59 Executor executor) { 60 return Futures.catching(input, exceptionType, fallback, executor); 61 } 62 catchingAsync( ListenableFuture<? extends V> input, Class<X> exceptionType, AsyncFunction<? super X, ? extends V> fallback, Executor executor)63 public static <V extends @Nullable Object, X extends Throwable> ListenableFuture<V> catchingAsync( 64 ListenableFuture<? extends V> input, 65 Class<X> exceptionType, 66 AsyncFunction<? super X, ? extends V> fallback, 67 Executor executor) { 68 return Futures.catchingAsync(input, exceptionType, fallback, executor); 69 } 70 submit( Callable<V> callable, Executor executor)71 public static <V extends @Nullable Object> ListenableFuture<V> submit( 72 Callable<V> callable, Executor executor) { 73 return Futures.submit(callable, executor); 74 } 75 submit(Runnable runnable, Executor executor)76 public static ListenableFuture<@Nullable Void> submit(Runnable runnable, Executor executor) { 77 return Futures.submit(runnable, executor); 78 } 79 submitAsync( AsyncCallable<V> callable, Executor executor)80 public static <V extends @Nullable Object> ListenableFuture<V> submitAsync( 81 AsyncCallable<V> callable, Executor executor) { 82 return Futures.submitAsync(callable, executor); 83 } 84 scheduleAsync( AsyncCallable<V> callable, long delay, TimeUnit timeUnit, ScheduledExecutorService executor)85 public static <V extends @Nullable Object> ListenableFuture<V> scheduleAsync( 86 AsyncCallable<V> callable, long delay, TimeUnit timeUnit, ScheduledExecutorService executor) { 87 return Futures.scheduleAsync(callable, delay, timeUnit, executor); 88 } 89 90 @SafeVarargs whenAllComplete( ListenableFuture<? extends V>.... futures)91 public static <V extends @Nullable Object> PropagatedFutureCombiner<V> whenAllComplete( 92 ListenableFuture<? extends V>... futures) { 93 return new PropagatedFutureCombiner<>(Futures.whenAllComplete(futures)); 94 } 95 whenAllComplete( Iterable<? extends ListenableFuture<? extends V>> futures)96 public static <V extends @Nullable Object> PropagatedFutureCombiner<V> whenAllComplete( 97 Iterable<? extends ListenableFuture<? extends V>> futures) { 98 return new PropagatedFutureCombiner<>(Futures.whenAllComplete(futures)); 99 } 100 101 @SafeVarargs whenAllSucceed( ListenableFuture<? extends V>.... futures)102 public static <V extends @Nullable Object> PropagatedFutureCombiner<V> whenAllSucceed( 103 ListenableFuture<? extends V>... futures) { 104 return new PropagatedFutureCombiner<>(Futures.whenAllSucceed(futures)); 105 } 106 whenAllSucceed( Iterable<? extends ListenableFuture<? extends V>> futures)107 public static <V extends @Nullable Object> PropagatedFutureCombiner<V> whenAllSucceed( 108 Iterable<? extends ListenableFuture<? extends V>> futures) { 109 return new PropagatedFutureCombiner<>(Futures.whenAllSucceed(futures)); 110 } 111 112 /** Wrapper around {@link FutureCombiner}. */ 113 public static final class PropagatedFutureCombiner<V extends @Nullable Object> { 114 private final FutureCombiner<V> futureCombiner; 115 PropagatedFutureCombiner(FutureCombiner<V> futureCombiner)116 private PropagatedFutureCombiner(FutureCombiner<V> futureCombiner) { 117 this.futureCombiner = futureCombiner; 118 } 119 callAsync( AsyncCallable<C> combiner, Executor executor)120 public <C extends @Nullable Object> ListenableFuture<C> callAsync( 121 AsyncCallable<C> combiner, Executor executor) { 122 return futureCombiner.callAsync(combiner, executor); 123 } 124 call( Callable<C> combiner, Executor executor)125 public <C extends @Nullable Object> ListenableFuture<C> call( 126 Callable<C> combiner, Executor executor) { 127 return futureCombiner.call(combiner, executor); 128 } 129 run(final Runnable combiner, Executor executor)130 public ListenableFuture<?> run(final Runnable combiner, Executor executor) { 131 return futureCombiner.run(combiner, executor); 132 } 133 } 134 } 135