1 /*
2  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
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  * A copy of the License is located at
7  *
8  *  http://aws.amazon.com/apache2.0
9  *
10  * or in the "license" file accompanying this file. This file is distributed
11  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12  * express or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */

15
16 package software.amazon.awssdk.utils.cache;
17
18 import java.time.Instant;
19 import java.util.function.Supplier;
20 import software.amazon.awssdk.annotations.SdkProtectedApi;
21
22 /**
23  * A wrapper for the value returned by the {@link Supplier} underlying a {@link CachedSupplier}. The underlying {@link Supplier}
24  * returns this to specify when the underlying value should be refreshed.
25  */

26 @SdkProtectedApi
27 public final class RefreshResult<T> {
28     private final T value;
29     private final Instant staleTime;
30     private final Instant prefetchTime;
31
32     private RefreshResult(Builder<T> builder) {
33         this.value = builder.value;
34         this.staleTime = builder.staleTime;
35         this.prefetchTime = builder.prefetchTime;
36     }
37
38     /**
39      * Get a builder for creating a {@link RefreshResult}.
40      *
41      * @param value The value that should be cached by the supplier.
42      */

43     public static <T> Builder<T> builder(T value) {
44         return new Builder<>(value);
45     }
46
47     /**
48      * The value resulting from the refresh.
49      */

50     public T value() {
51         return value;
52     }
53
54     /**
55      * When the configured value is stale and should not longer be used. All threads will block until the value is updated.
56      */

57     public Instant staleTime() {
58         return staleTime;
59     }
60
61     /**
62      * When the configured value is getting close to stale and should be updated using the supplier's
63      * {@link CachedSupplier#prefetchStrategy}.
64      */

65     public Instant prefetchTime() {
66         return prefetchTime;
67     }
68
69     /**
70      * A builder for a {@link RefreshResult}.
71      */

72     public static final class Builder<T> {
73         private final T value;
74         private Instant staleTime = Instant.MAX;
75         private Instant prefetchTime = Instant.MAX;
76
77         private Builder(T value) {
78             this.value = value;
79         }
80
81         /**
82          * Specify the time at which the value in this cache is stale, and all calls to {@link CachedSupplier#get()} should block
83          * to try to update the value.
84          *
85          * If this isn't specified, all threads will never block to update the value.
86          */

87         public Builder<T> staleTime(Instant staleTime) {
88             this.staleTime = staleTime;
89             return this;
90         }
91
92         /**
93          * Specify the time at which a thread that calls {@link CachedSupplier#get()} should trigger a cache prefetch. The
94          * exact behavior of a "prefetch" is defined when the cache is created with
95          * {@link CachedSupplier.Builder#prefetchStrategy(CachedSupplier.PrefetchStrategy)}, and may either have one thread block
96          * to refresh the cache or have an asynchronous task reload the value in the background.
97          *
98          * If this isn't specified, the prefetch strategy will never be used and all threads will block to update the value when
99          * the {@link #staleTime(Instant)} arrives.
100          */

101         public Builder<T> prefetchTime(Instant prefetchTime) {
102             this.prefetchTime = prefetchTime;
103             return this;
104         }
105
106         /**
107          * Build a {@link RefreshResult} using the values currently configured in this builder.
108          */

109         public RefreshResult<T> build() {
110             return new RefreshResult<>(this);
111         }
112     }
113 }
114