Skip to content

Commit 216b72a

Browse files
authored
Add few improvements/fixes (matching guava): (googleapis#29)
1) Add ApiFutures.addCallback() method overloaded version which accepts executor 2) Add ApiFutures.immediateCancelledFuture() method 3) Remove "settability" from AbstractApiFuture and make that functionality available only in SettableApiFuture settable.
1 parent c3c17c5 commit 216b72a

4 files changed

Lines changed: 63 additions & 11 deletions

File tree

src/main/java/com/google/api/core/AbstractApiFuture.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,11 @@ public boolean isDone() {
7070
return impl.isDone();
7171
}
7272

73-
public boolean set(V value) {
73+
protected boolean set(V value) {
7474
return impl.set(value);
7575
}
7676

77-
public boolean setException(Throwable throwable) {
77+
protected boolean setException(Throwable throwable) {
7878
return impl.setException(throwable);
7979
}
8080

@@ -87,12 +87,12 @@ ListenableFuture<V> getInternalListenableFuture() {
8787

8888
private class InternalSettableFuture extends AbstractFuture<V> {
8989
@Override
90-
public boolean set(@Nullable V value) {
90+
protected boolean set(@Nullable V value) {
9191
return super.set(value);
9292
}
9393

9494
@Override
95-
public boolean setException(Throwable throwable) {
95+
protected boolean setException(Throwable throwable) {
9696
return super.setException(throwable);
9797
}
9898

src/main/java/com/google/api/core/ApiFutures.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,16 @@
3030
*/
3131
package com.google.api.core;
3232

33+
import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
34+
3335
import com.google.common.base.Function;
3436
import com.google.common.collect.Iterables;
3537
import com.google.common.util.concurrent.AsyncFunction;
3638
import com.google.common.util.concurrent.FutureCallback;
3739
import com.google.common.util.concurrent.Futures;
3840
import com.google.common.util.concurrent.ListenableFuture;
3941
import java.util.List;
42+
import java.util.concurrent.Executor;
4043
import javax.annotation.Nullable;
4144

4245
/** Static utility methods for the {@link ApiFuture} interface. */
@@ -45,6 +48,11 @@ private ApiFutures() {}
4548

4649
public static <V> void addCallback(
4750
final ApiFuture<V> future, final ApiFutureCallback<? super V> callback) {
51+
addCallback(future, callback, directExecutor());
52+
}
53+
54+
public static <V> void addCallback(
55+
final ApiFuture<V> future, final ApiFutureCallback<? super V> callback, Executor executor) {
4856
Futures.addCallback(
4957
listenableFutureForApiFuture(future),
5058
new FutureCallback<V>() {
@@ -57,7 +65,8 @@ public void onFailure(Throwable t) {
5765
public void onSuccess(V v) {
5866
callback.onSuccess(v);
5967
}
60-
});
68+
},
69+
executor);
6170
}
6271

6372
public static <V, X extends Throwable> ApiFuture<V> catching(
@@ -80,6 +89,10 @@ public static <V> ApiFuture<V> immediateFailedFuture(Throwable throwable) {
8089
return new ListenableFutureToApiFuture<V>(Futures.<V>immediateFailedFuture(throwable));
8190
}
8291

92+
public static <V> ApiFuture<V> immediateCancelledFuture() {
93+
return new ListenableFutureToApiFuture<V>(Futures.<V>immediateCancelledFuture());
94+
}
95+
8396
public static <V, X> ApiFuture<X> transform(
8497
ApiFuture<? extends V> input, final ApiFunction<? super V, ? extends X> function) {
8598
return new ListenableFutureToApiFuture<>(

src/main/java/com/google/api/core/SettableApiFuture.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,14 @@ private SettableApiFuture() {}
4242
public static <V> SettableApiFuture<V> create() {
4343
return new SettableApiFuture<>();
4444
}
45+
46+
@Override
47+
protected boolean set(V value) {
48+
return super.set(value);
49+
}
50+
51+
@Override
52+
protected boolean setException(Throwable throwable) {
53+
return super.setException(throwable);
54+
}
4555
}

src/test/java/com/google/api/core/ApiFuturesTest.java

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,12 @@
3030
*/
3131
package com.google.api.core;
3232

33+
import static com.google.common.truth.Truth.assertThat;
34+
3335
import com.google.common.collect.ImmutableList;
34-
import com.google.common.truth.Truth;
3536
import java.util.List;
37+
import java.util.concurrent.CancellationException;
38+
import java.util.concurrent.ExecutionException;
3639
import java.util.concurrent.atomic.AtomicInteger;
3740
import org.junit.Test;
3841

@@ -56,7 +59,7 @@ public void onFailure(Throwable t) {
5659
}
5760
});
5861
future.set(0);
59-
Truth.assertThat(flag.get()).isEqualTo(1);
62+
assertThat(flag.get()).isEqualTo(1);
6063
}
6164

6265
@Test
@@ -73,7 +76,7 @@ public Integer apply(Exception ex) {
7376
}
7477
});
7578
future.setException(new Exception());
76-
Truth.assertThat(fallback.get()).isEqualTo(42);
79+
assertThat(fallback.get()).isEqualTo(42);
7780
}
7881

7982
@Test
@@ -89,7 +92,7 @@ public String apply(Integer input) {
8992
}
9093
});
9194
inputFuture.set(6);
92-
Truth.assertThat(transformedFuture.get()).isEqualTo("6");
95+
assertThat(transformedFuture.get()).isEqualTo("6");
9396
}
9497

9598
@Test
@@ -100,7 +103,7 @@ public void testAllAsList() throws Exception {
100103
ApiFutures.allAsList(ImmutableList.of(inputFuture1, inputFuture2));
101104
inputFuture1.set(1);
102105
inputFuture2.set(2);
103-
Truth.assertThat(listFuture.get()).containsExactly(1, 2).inOrder();
106+
assertThat(listFuture.get()).containsExactly(1, 2).inOrder();
104107
}
105108

106109
@Test
@@ -115,6 +118,32 @@ public ApiFuture<Integer> apply(Integer input) {
115118
return ApiFutures.immediateFuture(input + 1);
116119
}
117120
});
118-
Truth.assertThat(outputFuture.get()).isEqualTo(1);
121+
assertThat(outputFuture.get()).isEqualTo(1);
122+
}
123+
124+
@Test
125+
public void testImmediateFailedFuture() throws InterruptedException {
126+
ApiFuture<String> future =
127+
ApiFutures.immediateFailedFuture(new IllegalArgumentException("The message"));
128+
IllegalArgumentException exception = null;
129+
try {
130+
future.get();
131+
} catch (ExecutionException e) {
132+
exception = (IllegalArgumentException) e.getCause();
133+
}
134+
assertThat(exception).isNotNull();
135+
assertThat(exception.getMessage()).isEqualTo("The message");
136+
}
137+
138+
@Test
139+
public void testImmediateCancelledFuture() throws InterruptedException, ExecutionException {
140+
ApiFuture<String> future = ApiFutures.immediateCancelledFuture();
141+
CancellationException exception = null;
142+
try {
143+
future.get();
144+
} catch (CancellationException e) {
145+
exception = e;
146+
}
147+
assertThat(exception).isNotNull();
119148
}
120149
}

0 commit comments

Comments
 (0)