1717package org .dataloader ;
1818
1919import org .dataloader .annotations .PublicApi ;
20+ import org .dataloader .annotations .VisibleForTesting ;
2021import org .dataloader .impl .CompletableFutureKit ;
2122import org .dataloader .stats .Statistics ;
2223import org .dataloader .stats .StatisticsCollector ;
2324
25+ import java .time .Clock ;
26+ import java .time .Instant ;
2427import java .util .ArrayList ;
2528import java .util .Collections ;
2629import java .util .List ;
5255 *
5356 * @param <K> type parameter indicating the type of the data load keys
5457 * @param <V> type parameter indicating the type of the data that is returned
58+ *
5559 * @author <a href="https://github.com/aschrijver/">Arnold Schrijver</a>
5660 * @author <a href="https://github.com/bbakerman/">Brad Baker</a>
5761 */
@@ -69,6 +73,7 @@ public class DataLoader<K, V> {
6973 * @param batchLoadFunction the batch load function to use
7074 * @param <K> the key type
7175 * @param <V> the value type
76+ *
7277 * @return a new DataLoader
7378 */
7479 public static <K , V > DataLoader <K , V > newDataLoader (BatchLoader <K , V > batchLoadFunction ) {
@@ -82,6 +87,7 @@ public static <K, V> DataLoader<K, V> newDataLoader(BatchLoader<K, V> batchLoadF
8287 * @param options the options to use
8388 * @param <K> the key type
8489 * @param <V> the value type
90+ *
8591 * @return a new DataLoader
8692 */
8793 public static <K , V > DataLoader <K , V > newDataLoader (BatchLoader <K , V > batchLoadFunction , DataLoaderOptions options ) {
@@ -102,6 +108,7 @@ public static <K, V> DataLoader<K, V> newDataLoader(BatchLoader<K, V> batchLoadF
102108 * @param batchLoadFunction the batch load function to use that uses {@link org.dataloader.Try} objects
103109 * @param <K> the key type
104110 * @param <V> the value type
111+ *
105112 * @return a new DataLoader
106113 */
107114 public static <K , V > DataLoader <K , V > newDataLoaderWithTry (BatchLoader <K , Try <V >> batchLoadFunction ) {
@@ -117,7 +124,9 @@ public static <K, V> DataLoader<K, V> newDataLoaderWithTry(BatchLoader<K, Try<V>
117124 * @param options the options to use
118125 * @param <K> the key type
119126 * @param <V> the value type
127+ *
120128 * @return a new DataLoader
129+ *
121130 * @see #newDataLoaderWithTry(BatchLoader)
122131 */
123132 @ SuppressWarnings ("unchecked" )
@@ -132,6 +141,7 @@ public static <K, V> DataLoader<K, V> newDataLoaderWithTry(BatchLoader<K, Try<V>
132141 * @param batchLoadFunction the batch load function to use
133142 * @param <K> the key type
134143 * @param <V> the value type
144+ *
135145 * @return a new DataLoader
136146 */
137147 public static <K , V > DataLoader <K , V > newDataLoader (BatchLoaderWithContext <K , V > batchLoadFunction ) {
@@ -145,6 +155,7 @@ public static <K, V> DataLoader<K, V> newDataLoader(BatchLoaderWithContext<K, V>
145155 * @param options the options to use
146156 * @param <K> the key type
147157 * @param <V> the value type
158+ *
148159 * @return a new DataLoader
149160 */
150161 public static <K , V > DataLoader <K , V > newDataLoader (BatchLoaderWithContext <K , V > batchLoadFunction , DataLoaderOptions options ) {
@@ -165,6 +176,7 @@ public static <K, V> DataLoader<K, V> newDataLoader(BatchLoaderWithContext<K, V>
165176 * @param batchLoadFunction the batch load function to use that uses {@link org.dataloader.Try} objects
166177 * @param <K> the key type
167178 * @param <V> the value type
179+ *
168180 * @return a new DataLoader
169181 */
170182 public static <K , V > DataLoader <K , V > newDataLoaderWithTry (BatchLoaderWithContext <K , Try <V >> batchLoadFunction ) {
@@ -180,7 +192,9 @@ public static <K, V> DataLoader<K, V> newDataLoaderWithTry(BatchLoaderWithContex
180192 * @param options the options to use
181193 * @param <K> the key type
182194 * @param <V> the value type
195+ *
183196 * @return a new DataLoader
197+ *
184198 * @see #newDataLoaderWithTry(BatchLoader)
185199 */
186200 public static <K , V > DataLoader <K , V > newDataLoaderWithTry (BatchLoaderWithContext <K , Try <V >> batchLoadFunction , DataLoaderOptions options ) {
@@ -194,6 +208,7 @@ public static <K, V> DataLoader<K, V> newDataLoaderWithTry(BatchLoaderWithContex
194208 * @param batchLoadFunction the batch load function to use
195209 * @param <K> the key type
196210 * @param <V> the value type
211+ *
197212 * @return a new DataLoader
198213 */
199214 public static <K , V > DataLoader <K , V > newMappedDataLoader (MappedBatchLoader <K , V > batchLoadFunction ) {
@@ -207,6 +222,7 @@ public static <K, V> DataLoader<K, V> newMappedDataLoader(MappedBatchLoader<K, V
207222 * @param options the options to use
208223 * @param <K> the key type
209224 * @param <V> the value type
225+ *
210226 * @return a new DataLoader
211227 */
212228 public static <K , V > DataLoader <K , V > newMappedDataLoader (MappedBatchLoader <K , V > batchLoadFunction , DataLoaderOptions options ) {
@@ -228,6 +244,7 @@ public static <K, V> DataLoader<K, V> newMappedDataLoader(MappedBatchLoader<K, V
228244 * @param batchLoadFunction the batch load function to use that uses {@link org.dataloader.Try} objects
229245 * @param <K> the key type
230246 * @param <V> the value type
247+ *
231248 * @return a new DataLoader
232249 */
233250 public static <K , V > DataLoader <K , V > newMappedDataLoaderWithTry (MappedBatchLoader <K , Try <V >> batchLoadFunction ) {
@@ -243,7 +260,9 @@ public static <K, V> DataLoader<K, V> newMappedDataLoaderWithTry(MappedBatchLoad
243260 * @param options the options to use
244261 * @param <K> the key type
245262 * @param <V> the value type
263+ *
246264 * @return a new DataLoader
265+ *
247266 * @see #newDataLoaderWithTry(BatchLoader)
248267 */
249268 public static <K , V > DataLoader <K , V > newMappedDataLoaderWithTry (MappedBatchLoader <K , Try <V >> batchLoadFunction , DataLoaderOptions options ) {
@@ -257,6 +276,7 @@ public static <K, V> DataLoader<K, V> newMappedDataLoaderWithTry(MappedBatchLoad
257276 * @param batchLoadFunction the batch load function to use
258277 * @param <K> the key type
259278 * @param <V> the value type
279+ *
260280 * @return a new DataLoader
261281 */
262282 public static <K , V > DataLoader <K , V > newMappedDataLoader (MappedBatchLoaderWithContext <K , V > batchLoadFunction ) {
@@ -270,6 +290,7 @@ public static <K, V> DataLoader<K, V> newMappedDataLoader(MappedBatchLoaderWithC
270290 * @param options the options to use
271291 * @param <K> the key type
272292 * @param <V> the value type
293+ *
273294 * @return a new DataLoader
274295 */
275296 public static <K , V > DataLoader <K , V > newMappedDataLoader (MappedBatchLoaderWithContext <K , V > batchLoadFunction , DataLoaderOptions options ) {
@@ -290,6 +311,7 @@ public static <K, V> DataLoader<K, V> newMappedDataLoader(MappedBatchLoaderWithC
290311 * @param batchLoadFunction the batch load function to use that uses {@link org.dataloader.Try} objects
291312 * @param <K> the key type
292313 * @param <V> the value type
314+ *
293315 * @return a new DataLoader
294316 */
295317 public static <K , V > DataLoader <K , V > newMappedDataLoaderWithTry (MappedBatchLoaderWithContext <K , Try <V >> batchLoadFunction ) {
@@ -305,7 +327,9 @@ public static <K, V> DataLoader<K, V> newMappedDataLoaderWithTry(MappedBatchLoad
305327 * @param options the options to use
306328 * @param <K> the key type
307329 * @param <V> the value type
330+ *
308331 * @return a new DataLoader
332+ *
309333 * @see #newDataLoaderWithTry(BatchLoader)
310334 */
311335 public static <K , V > DataLoader <K , V > newMappedDataLoaderWithTry (MappedBatchLoaderWithContext <K , Try <V >> batchLoadFunction , DataLoaderOptions options ) {
@@ -337,14 +361,30 @@ private DataLoader(Object batchLoadFunction, DataLoaderOptions options) {
337361 // order of keys matter in data loader
338362 this .stats = nonNull (loaderOptions .getStatisticsCollector ());
339363
340- this .helper = new DataLoaderHelper <>(this , batchLoadFunction , loaderOptions , this .futureCache , this .stats );
364+ this .helper = new DataLoaderHelper <>(this , batchLoadFunction , loaderOptions , this .futureCache , this .stats , clock ());
365+ }
366+
367+ @ VisibleForTesting
368+ Clock clock () {
369+ return Clock .systemUTC ();
341370 }
342371
343372 @ SuppressWarnings ("unchecked" )
344373 private CacheMap <Object , CompletableFuture <V >> determineCacheMap (DataLoaderOptions loaderOptions ) {
345374 return loaderOptions .cacheMap ().isPresent () ? (CacheMap <Object , CompletableFuture <V >>) loaderOptions .cacheMap ().get () : CacheMap .simpleMap ();
346375 }
347376
377+
378+ /**
379+ * This returns the last instant the data loader was dispatched. When the data loader is created this value is set to now.
380+ *
381+ * @return the instant since the last dispatch
382+ */
383+ public Instant getLastDispatchTime () {
384+ return helper .getLastDispatchTime ();
385+ }
386+
387+
348388 /**
349389 * Requests to load the data with the specified key asynchronously, and returns a future of the resulting value.
350390 * <p>
@@ -353,6 +393,7 @@ private CacheMap<Object, CompletableFuture<V>> determineCacheMap(DataLoaderOptio
353393 * and returned from cache).
354394 *
355395 * @param key the key to load
396+ *
356397 * @return the future of the value
357398 */
358399 public CompletableFuture <V > load (K key ) {
@@ -370,6 +411,7 @@ public CompletableFuture<V> load(K key) {
370411 * NOTE : This will NOT cause a data load to happen. You must called {@link #load(Object)} for that to happen.
371412 *
372413 * @param key the key to check
414+ *
373415 * @return an Optional to the future of the value
374416 */
375417 public Optional <CompletableFuture <V >> getIfPresent (K key ) {
@@ -388,6 +430,7 @@ public Optional<CompletableFuture<V>> getIfPresent(K key) {
388430 * NOTE : This will NOT cause a data load to happen. You must called {@link #load(Object)} for that to happen.
389431 *
390432 * @param key the key to check
433+ *
391434 * @return an Optional to the future of the value
392435 */
393436 public Optional <CompletableFuture <V >> getIfCompleted (K key ) {
@@ -407,6 +450,7 @@ public Optional<CompletableFuture<V>> getIfCompleted(K key) {
407450 *
408451 * @param key the key to load
409452 * @param keyContext a context object that is specific to this key
453+ *
410454 * @return the future of the value
411455 */
412456 public CompletableFuture <V > load (K key , Object keyContext ) {
@@ -422,6 +466,7 @@ public CompletableFuture<V> load(K key, Object keyContext) {
422466 * and returned from cache).
423467 *
424468 * @param keys the list of keys to load
469+ *
425470 * @return the composite future of the list of values
426471 */
427472 public CompletableFuture <List <V >> loadMany (List <K > keys ) {
@@ -441,6 +486,7 @@ public CompletableFuture<List<V>> loadMany(List<K> keys) {
441486 *
442487 * @param keys the list of keys to load
443488 * @param keyContexts the list of key calling context objects
489+ *
444490 * @return the composite future of the list of values
445491 */
446492 public CompletableFuture <List <V >> loadMany (List <K > keys , List <Object > keyContexts ) {
@@ -517,6 +563,7 @@ public int dispatchDepth() {
517563 * on the next load request.
518564 *
519565 * @param key the key to remove
566+ *
520567 * @return the data loader for fluent coding
521568 */
522569 public DataLoader <K , V > clear (K key ) {
@@ -544,6 +591,7 @@ public DataLoader<K, V> clearAll() {
544591 *
545592 * @param key the key
546593 * @param value the value
594+ *
547595 * @return the data loader for fluent coding
548596 */
549597 public DataLoader <K , V > prime (K key , V value ) {
@@ -561,6 +609,7 @@ public DataLoader<K, V> prime(K key, V value) {
561609 *
562610 * @param key the key
563611 * @param error the exception to prime instead of a value
612+ *
564613 * @return the data loader for fluent coding
565614 */
566615 public DataLoader <K , V > prime (K key , Exception error ) {
@@ -578,6 +627,7 @@ public DataLoader<K, V> prime(K key, Exception error) {
578627 * If no cache key function is present in {@link DataLoaderOptions}, then the returned value equals the input key.
579628 *
580629 * @param key the input key
630+ *
581631 * @return the cache key after the input is transformed with the cache key function
582632 */
583633 public Object getCacheKey (K key ) {
0 commit comments