Skip to content

Commit 141495b

Browse files
committed
If caching is off AND batching is off - ValueCache should not be used
1 parent e5e5bf5 commit 141495b

3 files changed

Lines changed: 65 additions & 5 deletions

File tree

src/main/java/org/dataloader/DataLoaderHelper.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ CompletableFuture<V> load(K key, Object loadContext) {
175175
} else {
176176
stats.incrementBatchLoadCountBy(1, new IncrementBatchLoadCountByStatisticsContext<>(key, loadContext));
177177
// immediate execution of batch function
178-
loadCallFuture = invokeLoaderImmediately(key, loadContext, true);
178+
loadCallFuture = invokeLoaderImmediately(key, loadContext, loaderOptions.cachingEnabled());
179179
if (futureCachingEnabled) {
180180
CompletableFuture<V> cachedFuture = futureCache.putIfAbsentAtomically(cacheKey, loadCallFuture);
181181
if (cachedFuture != null) {
@@ -228,6 +228,7 @@ DispatchResult<V> dispatch() {
228228
boolean batchingEnabled = loaderOptions.batchingEnabled();
229229

230230
LoaderQueueEntry<K, V> loaderQueueEntryHead;
231+
//noinspection ConditionalBreakInInfiniteLoop
231232
while (true) {
232233
loaderQueueEntryHead = loaderQueue.get();
233234
if (loaderQueue.compareAndSet(loaderQueueEntryHead, null)) {
@@ -244,7 +245,7 @@ DispatchResult<V> dispatch() {
244245
int queueSize = loaderQueueEntryHead.queueSize;
245246
// we copy the pre-loaded set of futures ready for dispatch
246247
Object[] keysArray = new Object[queueSize];
247-
CompletableFuture[] queuedFuturesArray = new CompletableFuture[queueSize];
248+
CompletableFuture<V>[] queuedFuturesArray = new CompletableFuture[queueSize];
248249
Object[] callContextsArray = new Object[queueSize];
249250
int index = queueSize - 1;
250251
while (loaderQueueEntryHead != null) {

src/test/java/org/dataloader/DataLoaderTest.java

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import org.awaitility.Duration;
2020
import org.dataloader.fixtures.CustomCacheMap;
21+
import org.dataloader.fixtures.CustomValueCache;
2122
import org.dataloader.fixtures.JsonObject;
2223
import org.dataloader.fixtures.User;
2324
import org.dataloader.fixtures.UserManager;
@@ -70,6 +71,8 @@
7071
import static org.hamcrest.Matchers.equalTo;
7172
import static org.hamcrest.Matchers.instanceOf;
7273
import static org.hamcrest.Matchers.is;
74+
import static org.hamcrest.Matchers.not;
75+
import static org.hamcrest.Matchers.sameInstance;
7376
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
7477
import static org.junit.jupiter.api.Assertions.assertEquals;
7578
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -1009,16 +1012,27 @@ public void should_degrade_gracefully_if_cache_get_throws(TestDataLoaderFactory
10091012
@MethodSource("org.dataloader.fixtures.parameterized.TestDataLoaderFactories#get")
10101013
public void batching_disabled_should_dispatch_immediately(TestDataLoaderFactory factory) {
10111014
List<Collection<String>> loadCalls = new ArrayList<>();
1012-
DataLoaderOptions options = newOptions().setBatchingEnabled(false).build();
1015+
1016+
CacheMap<String, String> cacheMap = CacheMap.simpleMap();
1017+
CustomValueCache valueCache = new CustomValueCache();
1018+
1019+
DataLoaderOptions options = newOptions().setBatchingEnabled(false)
1020+
.setCacheMap(cacheMap).setValueCache(valueCache).build();
10131021
DataLoader<String, String> identityLoader = factory.idLoader(options, loadCalls);
10141022

10151023
CompletableFuture<String> fa = identityLoader.load("A");
10161024
CompletableFuture<String> fb = identityLoader.load("B");
10171025

1026+
assertThat(cacheMap.size(), equalTo(2));
1027+
assertThat(valueCache.asMap().size(), equalTo(2));
1028+
10181029
// caching is on still
10191030
CompletableFuture<String> fa1 = identityLoader.load("A");
10201031
CompletableFuture<String> fb1 = identityLoader.load("B");
10211032

1033+
assertThat(fa, sameInstance(fa1));
1034+
assertThat(fb, sameInstance(fb1));
1035+
10221036
List<String> values = CompletableFutureKit.allOf(asList(fa, fb, fa1, fb1)).join();
10231037

10241038
assertThat(fa.join(), equalTo("A"));
@@ -1038,16 +1052,27 @@ public void batching_disabled_should_dispatch_immediately(TestDataLoaderFactory
10381052
@MethodSource("org.dataloader.fixtures.parameterized.TestDataLoaderFactories#get")
10391053
public void batching_disabled_and_caching_disabled_should_dispatch_immediately_and_forget(TestDataLoaderFactory factory) {
10401054
List<Collection<String>> loadCalls = new ArrayList<>();
1041-
DataLoaderOptions options = newOptions().setBatchingEnabled(false).setCachingEnabled(false).build();
1055+
1056+
CacheMap<String, String> cacheMap = CacheMap.simpleMap();
1057+
CustomValueCache valueCache = new CustomValueCache();
1058+
1059+
DataLoaderOptions options = newOptions().setBatchingEnabled(false).setCachingEnabled(false)
1060+
.setCacheMap(cacheMap).setValueCache(valueCache).build();
10421061
DataLoader<String, String> identityLoader = factory.idLoader(options, loadCalls);
10431062

10441063
CompletableFuture<String> fa = identityLoader.load("A");
10451064
CompletableFuture<String> fb = identityLoader.load("B");
10461065

1047-
// caching is off
1066+
// caching is off - it should not go to the Value cache nor the future cache
1067+
assertThat(cacheMap.size(), equalTo(0));
1068+
assertThat(valueCache.asMap().size(), equalTo(0));
1069+
10481070
CompletableFuture<String> fa1 = identityLoader.load("A");
10491071
CompletableFuture<String> fb1 = identityLoader.load("B");
10501072

1073+
assertThat(fa, not(sameInstance(fa1)));
1074+
assertThat(fb, not(sameInstance(fb1)));
1075+
10511076
List<String> values = CompletableFutureKit.allOf(asList(fa, fb, fa1, fb1)).join();
10521077

10531078
assertThat(fa.join(), equalTo("A"));

src/test/java/org/dataloader/DataLoaderValueCacheTest.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,40 @@ public CompletableFuture<Object> get(String key) {
379379
assertTrue(customValueCache.asMap().isEmpty());
380380
}
381381

382+
@ParameterizedTest
383+
@MethodSource("org.dataloader.fixtures.parameterized.TestDataLoaderFactories#get")
384+
public void if_caching_is_off_and_batching_is_off_its_never_hit(TestDataLoaderFactory factory) {
385+
AtomicInteger getCalls = new AtomicInteger();
386+
CustomValueCache customValueCache = new CustomValueCache() {
387+
388+
@Override
389+
public CompletableFuture<Object> get(String key) {
390+
getCalls.incrementAndGet();
391+
return super.get(key);
392+
}
393+
};
394+
395+
List<Collection<String>> loadCalls = new ArrayList<>();
396+
DataLoaderOptions options = newOptions().setValueCache(customValueCache).setCachingEnabled(false).setBatchingEnabled(false).build();
397+
DataLoader<String, String> identityLoader = factory.idLoader(options, loadCalls);
398+
399+
CompletableFuture<String> fA = identityLoader.load("a");
400+
CompletableFuture<String> fB = identityLoader.load("b");
401+
CompletableFuture<String> fC = identityLoader.load("missC");
402+
CompletableFuture<String> fD = identityLoader.load("missD");
403+
404+
await().until(identityLoader.dispatch()::isDone);
405+
406+
assertThat(fA.join(), equalTo("a"));
407+
assertThat(fB.join(), equalTo("b"));
408+
assertThat(fC.join(), equalTo("missC"));
409+
assertThat(fD.join(), equalTo("missD"));
410+
411+
assertThat(loadCalls, equalTo(asList(singletonList("a"), singletonList("b"), singletonList("missC"), singletonList("missD"))));
412+
assertThat(getCalls.get(), equalTo(0));
413+
assertTrue(customValueCache.asMap().isEmpty());
414+
}
415+
382416
@ParameterizedTest
383417
@MethodSource("org.dataloader.fixtures.parameterized.TestDataLoaderFactories#get")
384418
public void if_everything_is_cached_no_batching_happens(TestDataLoaderFactory factory) {

0 commit comments

Comments
 (0)