-
Notifications
You must be signed in to change notification settings - Fork 51
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fail fast implementation for joinList
- Loading branch information
1 parent
25bbd6e
commit 5b82580
Showing
10 changed files
with
526 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,3 +4,4 @@ | |
target/ | ||
pom.xml.releaseBackup | ||
release.properties | ||
*.iml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package com.spotify.futures; | ||
|
||
import java.util.concurrent.CompletableFuture; | ||
import java.util.function.Function; | ||
|
||
/** | ||
* Provides execution metadata in relation to a group of completable futures. | ||
* | ||
* @author Jose Alavez | ||
* @since 0.3.3 | ||
*/ | ||
public class ExecutionMetadata { | ||
|
||
private final CompletableFuture<?>[] all; | ||
|
||
ExecutionMetadata(CompletableFuture<?>... all) { | ||
this.all = all; | ||
} | ||
|
||
private int accumulate(Function<CompletableFuture<?>, Boolean> fn) { | ||
int accumulator = 0; | ||
for (int i = 0; i < all.length; i++) { | ||
if (fn.apply(all[i])) { | ||
accumulator++; | ||
} | ||
} | ||
return accumulator; | ||
} | ||
|
||
/** | ||
* Returns the total of completable futures being combined. | ||
*/ | ||
public int getTotal() { | ||
return all.length; | ||
} | ||
|
||
/** | ||
* Returns the total of completable futures that have been completed normally, exceptionally or | ||
* via cancellation. | ||
* | ||
* @see CompletableFuture#isDone() | ||
*/ | ||
public int getDone() { | ||
return accumulate(CompletableFuture::isDone); | ||
} | ||
|
||
/** | ||
* Returns the total of completable futures that have been completed normally. | ||
* | ||
* @see CompletableFuture#isDone() | ||
* @see CompletableFuture#isCompletedExceptionally() | ||
*/ | ||
public int getCompletedNormally() { | ||
return accumulate( | ||
completableFuture -> | ||
completableFuture.isDone() && !completableFuture.isCompletedExceptionally()); | ||
} | ||
|
||
/** | ||
* Returns the total of completable futures that have been completed exceptionally, in any way. | ||
* | ||
* @see CompletableFuture#isCompletedExceptionally() | ||
*/ | ||
public int getCompletedExceptionally() { | ||
return accumulate(CompletableFuture::isCompletedExceptionally); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package com.spotify.futures; | ||
|
||
/** | ||
* Interface that defines fail fast behavior when combining several completion stages in a | ||
* completable future. | ||
* | ||
* @author Jose Alavez | ||
* @since 0.3.3 | ||
*/ | ||
public interface FailFast { | ||
|
||
/** | ||
* Evaluates if the {@code throwable} should lead to a fast failure when combining completion | ||
* stages together. A fast failure will not wait for all the combined stages to complete normally | ||
* or exceptionally. | ||
* | ||
* @param throwable A {@link Throwable} returned by a exceptionally completed stage. | ||
* @param executionMetadata A {@link ExecutionMetadata} that provides data related to current | ||
* execution. | ||
* @return {@code true} if the combined completable future should fail fast, {@code false} if | ||
* otherwise. | ||
*/ | ||
boolean failFast(Throwable throwable, ExecutionMetadata executionMetadata); | ||
|
||
/** | ||
* Specifies a {@link Throwable} instance to return when a combined completable future fail fast. | ||
* | ||
* @param origin A {@link Throwable} that originated the fail fast. | ||
* @return A {@link Throwable} to used to complete exceptionally a combined completable future. | ||
*/ | ||
Throwable withThrowable(Throwable origin); | ||
|
||
/** | ||
* Defines if all the incomplete stages should be cancelled when failing fast. | ||
* | ||
* @return {@code true} if all the incomplete stages should be cancelled when failing fast, {@code | ||
* false} if otherwise. | ||
*/ | ||
boolean cancelAll(); | ||
} |
59 changes: 59 additions & 0 deletions
59
src/main/java/com/spotify/futures/FailFastWithThrowable.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package com.spotify.futures; | ||
|
||
import static java.util.Arrays.asList; | ||
|
||
import java.util.Collection; | ||
|
||
/** | ||
* Fail fast implementation that completes exceptionally when one of the stages completes | ||
* exceptionally matching a specific throwable class. | ||
* | ||
* <p>This implementation maintains the originating {@link Throwable} causing the fast failure and | ||
* propagates it through the combined completable future. | ||
* | ||
* <p>This implementation cancels all the remaining incomplete completable futures when failing | ||
* fast. | ||
* | ||
* @author Jose Alavez | ||
* @see FailFast | ||
* @since 0.3.3 | ||
*/ | ||
public class FailFastWithThrowable implements FailFast { | ||
|
||
private final Collection<Class<? extends Throwable>> classes; | ||
|
||
/** | ||
* @see FailFastWithThrowable#FailFastWithThrowable(java.util.Collection) | ||
*/ | ||
@SafeVarargs | ||
public FailFastWithThrowable(Class<? extends Throwable>... throwableClasses) { | ||
this(asList(throwableClasses)); | ||
} | ||
|
||
/** | ||
* @param throwableClasses {@link Collection} of throwable classes to fail fast. | ||
*/ | ||
public FailFastWithThrowable(Collection<Class<? extends Throwable>> throwableClasses) { | ||
this.classes = throwableClasses; | ||
} | ||
|
||
@Override | ||
public boolean cancelAll() { | ||
return true; | ||
} | ||
|
||
@Override | ||
public Throwable withThrowable(Throwable origin) { | ||
return origin; | ||
} | ||
|
||
@Override | ||
public boolean failFast(Throwable throwable, ExecutionMetadata executionMetadata) { | ||
|
||
if (throwable.getCause() != null) { | ||
return classes.contains(throwable.getCause().getClass()); | ||
} | ||
|
||
return classes.contains(throwable.getClass()); | ||
} | ||
} |
Oops, something went wrong.