Skip to content

Commit 288be41

Browse files
authored
Merge pull request #148 from AlexandreCarlton/observer-batch-loader-proof-of-concept
Add a proof-of-concept for "Observer-like" batch loading
2 parents 1d78255 + ce115fd commit 288be41

12 files changed

+1925
-8
lines changed

build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ def getDevelopmentVersion() {
3030
version
3131
}
3232

33-
3433
def releaseVersion = System.env.RELEASE_VERSION
3534
version = releaseVersion ? releaseVersion : getDevelopmentVersion()
3635
group = 'com.graphql-java'
@@ -76,6 +75,7 @@ dependencies {
7675
testImplementation 'org.awaitility:awaitility:2.0.0'
7776
testImplementation 'io.projectreactor:reactor-core:3.6.6'
7877
testImplementation 'com.github.ben-manes.caffeine:caffeine:2.9.0'
78+
testImplementation 'io.projectreactor:reactor-core:3.6.6'
7979
}
8080

8181
task sourcesJar(type: Jar) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.dataloader;
2+
3+
import org.reactivestreams.Subscriber;
4+
5+
import java.util.List;
6+
7+
/**
8+
* A function that is invoked for batch loading a stream of data values indicated by the provided list of keys.
9+
* <p>
10+
* The function will call the provided {@link Subscriber} to process the values it has retrieved to allow
11+
* the future returned by {@link DataLoader#load(Object)} to complete as soon as the individual value is available
12+
* (rather than when all values have been retrieved).
13+
* <p>
14+
* <b>NOTE:</b> It is <b>required </b> that {@link Subscriber#onNext(V)} is invoked on each value in the same order as
15+
* the provided keys.
16+
*
17+
* @param <K> type parameter indicating the type of keys to use for data load requests.
18+
* @param <V> type parameter indicating the type of values returned
19+
*/
20+
public interface BatchPublisher<K, V> {
21+
void load(List<K> keys, Subscriber<V> subscriber);
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package org.dataloader;
2+
3+
import org.reactivestreams.Subscriber;
4+
5+
import java.util.List;
6+
7+
/**
8+
* An {@link BatchPublisher} with a {@link BatchLoaderEnvironment} provided as an extra parameter to {@link #load}.
9+
*/
10+
public interface BatchPublisherWithContext<K, V> {
11+
void load(List<K> keys, Subscriber<V> subscriber, BatchLoaderEnvironment environment);
12+
}

src/main/java/org/dataloader/DataLoaderFactory.java

+268
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,274 @@ public static <K, V> DataLoader<K, V> newMappedDataLoaderWithTry(MappedBatchLoad
278278
return mkDataLoader(batchLoadFunction, options);
279279
}
280280

281+
/**
282+
* Creates new DataLoader with the specified batch loader function and default options
283+
* (batching, caching and unlimited batch size).
284+
*
285+
* @param batchLoadFunction the batch load function to use
286+
* @param <K> the key type
287+
* @param <V> the value type
288+
*
289+
* @return a new DataLoader
290+
*/
291+
public static <K, V> DataLoader<K, V> newPublisherDataLoader(BatchPublisher<K, V> batchLoadFunction) {
292+
return newPublisherDataLoader(batchLoadFunction, null);
293+
}
294+
295+
/**
296+
* Creates new DataLoader with the specified batch loader function with the provided options
297+
*
298+
* @param batchLoadFunction the batch load function to use
299+
* @param options the options to use
300+
* @param <K> the key type
301+
* @param <V> the value type
302+
*
303+
* @return a new DataLoader
304+
*/
305+
public static <K, V> DataLoader<K, V> newPublisherDataLoader(BatchPublisher<K, V> batchLoadFunction, DataLoaderOptions options) {
306+
return mkDataLoader(batchLoadFunction, options);
307+
}
308+
309+
/**
310+
* Creates new DataLoader with the specified batch loader function and default options
311+
* (batching, caching and unlimited batch size) where the batch loader function returns a list of
312+
* {@link org.dataloader.Try} objects.
313+
* <p>
314+
* If it's important you to know the exact status of each item in a batch call and whether it threw exceptions then
315+
* you can use this form to create the data loader.
316+
* <p>
317+
* Using Try objects allows you to capture a value returned or an exception that might
318+
* have occurred trying to get a value. .
319+
*
320+
* @param batchLoadFunction the batch load function to use that uses {@link org.dataloader.Try} objects
321+
* @param <K> the key type
322+
* @param <V> the value type
323+
*
324+
* @return a new DataLoader
325+
*/
326+
public static <K, V> DataLoader<K, V> newPublisherDataLoaderWithTry(BatchPublisher<K, Try<V>> batchLoadFunction) {
327+
return newPublisherDataLoaderWithTry(batchLoadFunction, null);
328+
}
329+
330+
/**
331+
* Creates new DataLoader with the specified batch loader function and with the provided options
332+
* where the batch loader function returns a list of
333+
* {@link org.dataloader.Try} objects.
334+
*
335+
* @param batchLoadFunction the batch load function to use that uses {@link org.dataloader.Try} objects
336+
* @param options the options to use
337+
* @param <K> the key type
338+
* @param <V> the value type
339+
*
340+
* @return a new DataLoader
341+
*
342+
* @see #newDataLoaderWithTry(BatchLoader)
343+
*/
344+
public static <K, V> DataLoader<K, V> newPublisherDataLoaderWithTry(BatchPublisher<K, Try<V>> batchLoadFunction, DataLoaderOptions options) {
345+
return mkDataLoader(batchLoadFunction, options);
346+
}
347+
348+
/**
349+
* Creates new DataLoader with the specified batch loader function and default options
350+
* (batching, caching and unlimited batch size).
351+
*
352+
* @param batchLoadFunction the batch load function to use
353+
* @param <K> the key type
354+
* @param <V> the value type
355+
*
356+
* @return a new DataLoader
357+
*/
358+
public static <K, V> DataLoader<K, V> newPublisherDataLoader(BatchPublisherWithContext<K, V> batchLoadFunction) {
359+
return newPublisherDataLoader(batchLoadFunction, null);
360+
}
361+
362+
/**
363+
* Creates new DataLoader with the specified batch loader function with the provided options
364+
*
365+
* @param batchLoadFunction the batch load function to use
366+
* @param options the options to use
367+
* @param <K> the key type
368+
* @param <V> the value type
369+
*
370+
* @return a new DataLoader
371+
*/
372+
public static <K, V> DataLoader<K, V> newPublisherDataLoader(BatchPublisherWithContext<K, V> batchLoadFunction, DataLoaderOptions options) {
373+
return mkDataLoader(batchLoadFunction, options);
374+
}
375+
376+
/**
377+
* Creates new DataLoader with the specified batch loader function and default options
378+
* (batching, caching and unlimited batch size) where the batch loader function returns a list of
379+
* {@link org.dataloader.Try} objects.
380+
* <p>
381+
* If it's important you to know the exact status of each item in a batch call and whether it threw exceptions then
382+
* you can use this form to create the data loader.
383+
* <p>
384+
* Using Try objects allows you to capture a value returned or an exception that might
385+
* have occurred trying to get a value. .
386+
*
387+
* @param batchLoadFunction the batch load function to use that uses {@link org.dataloader.Try} objects
388+
* @param <K> the key type
389+
* @param <V> the value type
390+
*
391+
* @return a new DataLoader
392+
*/
393+
public static <K, V> DataLoader<K, V> newPublisherDataLoaderWithTry(BatchPublisherWithContext<K, Try<V>> batchLoadFunction) {
394+
return newPublisherDataLoaderWithTry(batchLoadFunction, null);
395+
}
396+
397+
/**
398+
* Creates new DataLoader with the specified batch loader function and with the provided options
399+
* where the batch loader function returns a list of
400+
* {@link org.dataloader.Try} objects.
401+
*
402+
* @param batchLoadFunction the batch load function to use that uses {@link org.dataloader.Try} objects
403+
* @param options the options to use
404+
* @param <K> the key type
405+
* @param <V> the value type
406+
*
407+
* @return a new DataLoader
408+
*
409+
* @see #newPublisherDataLoaderWithTry(BatchPublisher)
410+
*/
411+
public static <K, V> DataLoader<K, V> newPublisherDataLoaderWithTry(BatchPublisherWithContext<K, Try<V>> batchLoadFunction, DataLoaderOptions options) {
412+
return mkDataLoader(batchLoadFunction, options);
413+
}
414+
415+
/**
416+
* Creates new DataLoader with the specified batch loader function and default options
417+
* (batching, caching and unlimited batch size).
418+
*
419+
* @param batchLoadFunction the batch load function to use
420+
* @param <K> the key type
421+
* @param <V> the value type
422+
*
423+
* @return a new DataLoader
424+
*/
425+
public static <K, V> DataLoader<K, V> newMappedPublisherDataLoader(MappedBatchPublisher<K, V> batchLoadFunction) {
426+
return newMappedPublisherDataLoader(batchLoadFunction, null);
427+
}
428+
429+
/**
430+
* Creates new DataLoader with the specified batch loader function with the provided options
431+
*
432+
* @param batchLoadFunction the batch load function to use
433+
* @param options the options to use
434+
* @param <K> the key type
435+
* @param <V> the value type
436+
*
437+
* @return a new DataLoader
438+
*/
439+
public static <K, V> DataLoader<K, V> newMappedPublisherDataLoader(MappedBatchPublisher<K, V> batchLoadFunction, DataLoaderOptions options) {
440+
return mkDataLoader(batchLoadFunction, options);
441+
}
442+
443+
/**
444+
* Creates new DataLoader with the specified batch loader function and default options
445+
* (batching, caching and unlimited batch size) where the batch loader function returns a list of
446+
* {@link org.dataloader.Try} objects.
447+
* <p>
448+
* If it's important you to know the exact status of each item in a batch call and whether it threw exceptions then
449+
* you can use this form to create the data loader.
450+
* <p>
451+
* Using Try objects allows you to capture a value returned or an exception that might
452+
* have occurred trying to get a value. .
453+
*
454+
* @param batchLoadFunction the batch load function to use that uses {@link org.dataloader.Try} objects
455+
* @param <K> the key type
456+
* @param <V> the value type
457+
*
458+
* @return a new DataLoader
459+
*/
460+
public static <K, V> DataLoader<K, V> newMappedPublisherDataLoaderWithTry(MappedBatchPublisher<K, Try<V>> batchLoadFunction) {
461+
return newMappedPublisherDataLoaderWithTry(batchLoadFunction, null);
462+
}
463+
464+
/**
465+
* Creates new DataLoader with the specified batch loader function and with the provided options
466+
* where the batch loader function returns a list of
467+
* {@link org.dataloader.Try} objects.
468+
*
469+
* @param batchLoadFunction the batch load function to use that uses {@link org.dataloader.Try} objects
470+
* @param options the options to use
471+
* @param <K> the key type
472+
* @param <V> the value type
473+
*
474+
* @return a new DataLoader
475+
*
476+
* @see #newDataLoaderWithTry(BatchLoader)
477+
*/
478+
public static <K, V> DataLoader<K, V> newMappedPublisherDataLoaderWithTry(MappedBatchPublisher<K, Try<V>> batchLoadFunction, DataLoaderOptions options) {
479+
return mkDataLoader(batchLoadFunction, options);
480+
}
481+
482+
/**
483+
* Creates new DataLoader with the specified batch loader function and default options
484+
* (batching, caching and unlimited batch size).
485+
*
486+
* @param batchLoadFunction the batch load function to use
487+
* @param <K> the key type
488+
* @param <V> the value type
489+
*
490+
* @return a new DataLoader
491+
*/
492+
public static <K, V> DataLoader<K, V> newMappedPublisherDataLoader(MappedBatchPublisherWithContext<K, V> batchLoadFunction) {
493+
return newMappedPublisherDataLoader(batchLoadFunction, null);
494+
}
495+
496+
/**
497+
* Creates new DataLoader with the specified batch loader function with the provided options
498+
*
499+
* @param batchLoadFunction the batch load function to use
500+
* @param options the options to use
501+
* @param <K> the key type
502+
* @param <V> the value type
503+
*
504+
* @return a new DataLoader
505+
*/
506+
public static <K, V> DataLoader<K, V> newMappedPublisherDataLoader(MappedBatchPublisherWithContext<K, V> batchLoadFunction, DataLoaderOptions options) {
507+
return mkDataLoader(batchLoadFunction, options);
508+
}
509+
510+
/**
511+
* Creates new DataLoader with the specified batch loader function and default options
512+
* (batching, caching and unlimited batch size) where the batch loader function returns a list of
513+
* {@link org.dataloader.Try} objects.
514+
* <p>
515+
* If it's important you to know the exact status of each item in a batch call and whether it threw exceptions then
516+
* you can use this form to create the data loader.
517+
* <p>
518+
* Using Try objects allows you to capture a value returned or an exception that might
519+
* have occurred trying to get a value. .
520+
*
521+
* @param batchLoadFunction the batch load function to use that uses {@link org.dataloader.Try} objects
522+
* @param <K> the key type
523+
* @param <V> the value type
524+
*
525+
* @return a new DataLoader
526+
*/
527+
public static <K, V> DataLoader<K, V> newMappedPublisherDataLoaderWithTry(MappedBatchPublisherWithContext<K, Try<V>> batchLoadFunction) {
528+
return newMappedPublisherDataLoaderWithTry(batchLoadFunction, null);
529+
}
530+
531+
/**
532+
* Creates new DataLoader with the specified batch loader function and with the provided options
533+
* where the batch loader function returns a list of
534+
* {@link org.dataloader.Try} objects.
535+
*
536+
* @param batchLoadFunction the batch load function to use that uses {@link org.dataloader.Try} objects
537+
* @param options the options to use
538+
* @param <K> the key type
539+
* @param <V> the value type
540+
*
541+
* @return a new DataLoader
542+
*
543+
* @see #newMappedPublisherDataLoaderWithTry(MappedBatchPublisher)
544+
*/
545+
public static <K, V> DataLoader<K, V> newMappedPublisherDataLoaderWithTry(MappedBatchPublisherWithContext<K, Try<V>> batchLoadFunction, DataLoaderOptions options) {
546+
return mkDataLoader(batchLoadFunction, options);
547+
}
548+
281549
static <K, V> DataLoader<K, V> mkDataLoader(Object batchLoadFunction, DataLoaderOptions options) {
282550
return new DataLoader<>(batchLoadFunction, options);
283551
}

0 commit comments

Comments
 (0)