@@ -155,11 +155,13 @@ CompletableFuture<V> load(K key, Object loadContext) {
155
155
}
156
156
}
157
157
158
+ @ SuppressWarnings ("unchecked" )
158
159
Object getCacheKey (K key ) {
159
160
return loaderOptions .cacheKeyFunction ().isPresent () ?
160
161
loaderOptions .cacheKeyFunction ().get ().getKey (key ) : key ;
161
162
}
162
163
164
+ @ SuppressWarnings ("unchecked" )
163
165
Object getCacheKeyWithContext (K key , Object context ) {
164
166
return loaderOptions .cacheKeyFunction ().isPresent () ?
165
167
loaderOptions .cacheKeyFunction ().get ().getKeyWithContext (key , context ) : key ;
@@ -511,6 +513,7 @@ private CompletableFuture<List<V>> invokeBatchPublisher(List<K> keys, List<Objec
511
513
512
514
BatchLoaderScheduler batchLoaderScheduler = loaderOptions .getBatchLoaderScheduler ();
513
515
if (batchLoadFunction instanceof BatchPublisherWithContext ) {
516
+ //noinspection unchecked
514
517
BatchPublisherWithContext <K , V > loadFunction = (BatchPublisherWithContext <K , V >) batchLoadFunction ;
515
518
if (batchLoaderScheduler != null ) {
516
519
BatchLoaderScheduler .ScheduledBatchPublisherCall loadCall = () -> loadFunction .load (keys , subscriber , environment );
@@ -519,6 +522,7 @@ private CompletableFuture<List<V>> invokeBatchPublisher(List<K> keys, List<Objec
519
522
loadFunction .load (keys , subscriber , environment );
520
523
}
521
524
} else {
525
+ //noinspection unchecked
522
526
BatchPublisher <K , V > loadFunction = (BatchPublisher <K , V >) batchLoadFunction ;
523
527
if (batchLoaderScheduler != null ) {
524
528
BatchLoaderScheduler .ScheduledBatchPublisherCall loadCall = () -> loadFunction .load (keys , subscriber );
@@ -536,6 +540,7 @@ private CompletableFuture<List<V>> invokeMappedBatchPublisher(List<K> keys, List
536
540
537
541
BatchLoaderScheduler batchLoaderScheduler = loaderOptions .getBatchLoaderScheduler ();
538
542
if (batchLoadFunction instanceof MappedBatchPublisherWithContext ) {
543
+ //noinspection unchecked
539
544
MappedBatchPublisherWithContext <K , V > loadFunction = (MappedBatchPublisherWithContext <K , V >) batchLoadFunction ;
540
545
if (batchLoaderScheduler != null ) {
541
546
BatchLoaderScheduler .ScheduledBatchPublisherCall loadCall = () -> loadFunction .load (keys , subscriber , environment );
@@ -544,6 +549,7 @@ private CompletableFuture<List<V>> invokeMappedBatchPublisher(List<K> keys, List
544
549
loadFunction .load (keys , subscriber , environment );
545
550
}
546
551
} else {
552
+ //noinspection unchecked
547
553
MappedBatchPublisher <K , V > loadFunction = (MappedBatchPublisher <K , V >) batchLoadFunction ;
548
554
if (batchLoaderScheduler != null ) {
549
555
BatchLoaderScheduler .ScheduledBatchPublisherCall loadCall = () -> loadFunction .load (keys , subscriber );
@@ -670,21 +676,21 @@ public void onError(Throwable throwable) {
670
676
/*
671
677
* A value has arrived - how do we complete the future that's associated with it in a common way
672
678
*/
673
- void onNextValue (K key , V value , Object callContext , CompletableFuture <V > future ) {
679
+ void onNextValue (K key , V value , Object callContext , List < CompletableFuture <V >> futures ) {
674
680
if (value instanceof Try ) {
675
681
// we allow the batch loader to return a Try so we can better represent a computation
676
682
// that might have worked or not.
677
683
//noinspection unchecked
678
684
Try <V > tryValue = (Try <V >) value ;
679
685
if (tryValue .isSuccess ()) {
680
- future . complete (tryValue .get ());
686
+ futures . forEach ( f -> f . complete (tryValue .get () ));
681
687
} else {
682
688
stats .incrementLoadErrorCount (new IncrementLoadErrorCountStatisticsContext <>(key , callContext ));
683
- future . completeExceptionally (tryValue .getThrowable ());
689
+ futures . forEach ( f -> f . completeExceptionally (tryValue .getThrowable () ));
684
690
clearCacheKeys .add (key );
685
691
}
686
692
} else {
687
- future . complete (value );
693
+ futures . forEach ( f -> f . complete (value ) );
688
694
}
689
695
}
690
696
@@ -718,7 +724,7 @@ public synchronized void onNext(V value) {
718
724
K key = keys .get (idx );
719
725
Object callContext = callContexts .get (idx );
720
726
CompletableFuture <V > future = queuedFutures .get (idx );
721
- onNextValue (key , value , callContext , future );
727
+ onNextValue (key , value , callContext , List . of ( future ) );
722
728
723
729
completedValues .add (value );
724
730
idx ++;
@@ -754,7 +760,7 @@ public synchronized void onError(Throwable ex) {
754
760
private class DataLoaderMapEntrySubscriber extends DataLoaderSubscriberBase <Map .Entry <K , V >> {
755
761
756
762
private final Map <K , Object > callContextByKey ;
757
- private final Map <K , CompletableFuture <V >> queuedFutureByKey ;
763
+ private final Map <K , List < CompletableFuture <V >>> queuedFuturesByKey ;
758
764
private final Map <K , V > completedValuesByKey = new HashMap <>();
759
765
760
766
@@ -766,13 +772,13 @@ private DataLoaderMapEntrySubscriber(
766
772
) {
767
773
super (valuesFuture , keys , callContexts , queuedFutures );
768
774
this .callContextByKey = new HashMap <>();
769
- this .queuedFutureByKey = new HashMap <>();
775
+ this .queuedFuturesByKey = new HashMap <>();
770
776
for (int idx = 0 ; idx < queuedFutures .size (); idx ++) {
771
777
K key = keys .get (idx );
772
778
Object callContext = callContexts .get (idx );
773
779
CompletableFuture <V > queuedFuture = queuedFutures .get (idx );
774
780
callContextByKey .put (key , callContext );
775
- queuedFutureByKey . put (key , queuedFuture );
781
+ queuedFuturesByKey . computeIfAbsent (key , k -> new ArrayList <>()). add ( queuedFuture );
776
782
}
777
783
}
778
784
@@ -784,9 +790,9 @@ public synchronized void onNext(Map.Entry<K, V> entry) {
784
790
V value = entry .getValue ();
785
791
786
792
Object callContext = callContextByKey .get (key );
787
- CompletableFuture <V > future = queuedFutureByKey .get (key );
793
+ List < CompletableFuture <V >> futures = queuedFuturesByKey .get (key );
788
794
789
- onNextValue (key , value , callContext , future );
795
+ onNextValue (key , value , callContext , futures );
790
796
791
797
completedValuesByKey .put (key , value );
792
798
}
@@ -811,15 +817,16 @@ public synchronized void onError(Throwable ex) {
811
817
// Complete the futures for the remaining keys with the exception.
812
818
for (int idx = 0 ; idx < queuedFutures .size (); idx ++) {
813
819
K key = keys .get (idx );
814
- CompletableFuture <V > future = queuedFutureByKey .get (key );
820
+ List < CompletableFuture <V >> futures = queuedFuturesByKey .get (key );
815
821
if (!completedValuesByKey .containsKey (key )) {
816
- future .completeExceptionally (ex );
822
+ for (CompletableFuture <V > future : futures ) {
823
+ future .completeExceptionally (ex );
824
+ }
817
825
// clear any cached view of this key because they all failed
818
826
dataLoader .clear (key );
819
827
}
820
828
}
821
829
valuesFuture .completeExceptionally (ex );
822
830
}
823
-
824
831
}
825
832
}
0 commit comments