1 package com.atlassian.vcache;
2
3 import com.atlassian.annotations.ExperimentalApi;
4
5 import java.util.concurrent.CompletableFuture;
6 import java.util.concurrent.CompletionStage;
7 import java.util.function.BiFunction;
8 import java.util.function.Function;
9
10 /**
11 * Provides a helper utilities.
12 *
13 * @since 1.0
14 */
15 @ExperimentalApi
16 public class VCacheUtils {
17 /**
18 * Syntactic sugar for writing {@code stage.toCompletableFuture().unsafeJoin()}. This method should not be used
19 * in production code, as it should be resilient to cache failures.
20 *
21 * @param stage the stage to call {@link CompletableFuture#join()} on
22 * @param <V> the value type
23 * @return the result of joining.
24 * @see CompletableFuture#join()
25 * @see #unsafeJoin(CompletionStage)
26 * @deprecated since 1.5.0 - use {@link #unsafeJoin(CompletionStage)} instead (if you must).
27 */
28 @Deprecated
29 public static <V> V join(CompletionStage<V> stage) {
30 return stage.toCompletableFuture().join();
31 }
32
33 /**
34 * Syntactic sugar for writing {@code stage.toCompletableFuture().unsafeJoin()}. This method should not be used
35 * in production code, as it should be resilient to cache failures. This method will throw runtime exceptions
36 * if errors occur.
37 *
38 * @param stage the stage to call {@link CompletableFuture#join()} on
39 * @param <V> the value type
40 * @return the result of joining.
41 * @see CompletableFuture#join()
42 */
43 public static <V> V unsafeJoin(CompletionStage<V> stage) {
44 return stage.toCompletableFuture().join();
45 }
46
47 /**
48 * Syntactic sugar for handling the result (either success or failure) from a {@link CompletionStage}.
49 *
50 * @param stage the stage to handle the results
51 * @param success called if the stage returned a successful result
52 * @param failure called if the stage failed
53 * @param <T> the type returned by the stage
54 * @param <R> the type to be returned
55 * @return if the stage is successful, then the result of calling <tt>success</tt>, otherwise the result of
56 * calling <tt>failure</tt>
57 */
58 public static <T, R> R fold(CompletionStage<T> stage, Function<T, R> success, Function<Throwable, R> failure) {
59 return unsafeJoin(stage.handle((val, err) ->
60 (err != null) ? failure.apply(err) : success.apply(val)));
61 }
62
63 /**
64 * Syntactic sugar for writing {@code stage.handle(fn).toCompletableFuture().unsafeJoin()}.
65 *
66 * @param stage the stage to handle the results
67 * @param fn called to handle the result
68 * @param <T> the type returned by the stage
69 * @param <R> the type to be returned
70 * @return the result of calling <tt>fn</tt> on the stage outcome.
71 */
72 public static <T, R> R fold(CompletionStage<T> stage, BiFunction<T, Throwable, R> fn) {
73 return unsafeJoin(stage.handle(fn));
74 }
75 }