Skip to content

hjfeilg/java-dataloader

Repository files navigation

Vert.x DataLoader

Build Status   Apache licensed   Download

More documentation coming soon..

This small and simple utility library is a port of Facebook DataLoader to Java 8 for use with Vert.x. It can serve as integral part of your application's data layer to provide a consistent API over various back-ends and reduce message communication overhead through batching and caching.

An important use case for DataLoader is improving the efficiency of GraphQL query execution, but there are many other use cases where you can benefit from using this utility.

Most of the code is ported directly from Facebook's reference implementation, with one IMPORTANT adaptation to make it work for Java 8 and Vert.x. ([Find more on this in the paragraphs below]).

But before reading on, be sure to take a short dive into the original documentation provided by Lee Byron (@leebyron) and Nicholas Schrock (@schrockn) from Facebook, the creators of the original data loader.

Table of contents

Features

  • Simple, intuitive API, using generics and fluent coding
  • Define batch load function with lambda expression
  • Schedule a load request in queue for batching
  • Add load requests from anywhere in code
  • Request returns Future<V> of requested value
  • Can create multiple requests at once, returns CompositeFuture
  • Caches load requests, so data is only fetched once
  • Can clear individual cache keys, so data is fetched on next load request dispatch
  • Can prime the cache with key/values, to avoid data being fetched needlessly
  • Can configure cache key function with lambda expression to extract cache key from complex data loader key types
  • Dispatch load request queue when batch is prepared, returns CompositeFuture
  • Individual batch futures complete as batch is processed
  • CompositeFutures results are ordered according to insertion order of load requests
  • Deals with partial errors when a batch future fails
  • Can disable batching and/or caching in configuration
  • Can supply your own CacheMap<K, V> implementations
  • Has very high test coverage (see Acknowledgements)

Differences to reference implementation

Manual dispatching

The original data loader was written in Javascript for NodeJS. NodeJS is single-threaded in nature, but simulates asynchronous logic by invoking functions on separate threads in an event loop, as explained in this post on StackOverflow.

Vert.x on the other hand also uses an event loop (that you should not block!!), but comes with actor-like Verticles and a distributed EventBus that make it inherently asynchronous, and non-blocking.

Now in NodeJS generates so-call 'ticks' in which queued functions are dispatched for execution, and Facebook DataLoader uses the nextTick() function in NodeJS to automatically dequeue load requests and send them to the batch execution function for processing.

And here there is an IMPORTANT DIFFERENCE compared to how this data loader operates!!

In NodeJS the batch preparation will not affect the asynchronous processing behaviour in any way. It will just prepare batches in 'spare time' as it were.

This is different in Vert.x as you will actually delay the execution of your load requests, until the moment where you make a call to dataLoader.dispatch() in comparison to when you would just handle futures directly.

Does this make Java DataLoader any less useful than the reference implementation? I would argue this is not the case, and there are also gains to this different mode of operation:

  • In contrast to the NodeJS implementation you as developer are in full control of when batches are dispatched
  • You can attach any logic that determines when a dispatch takes place
  • You still retain all other features, full caching support and batching (e.g. to optimize message bus traffic, GraphQL query execution time, etc.)

However, with batch execution control comes responsibility! If you forget to make the call to dispatch() then the futures in the load request queue will never be batched, and thus will never complete! So be careful when crafting your loader designs.

Note: In future releases the danger of not invoking dispatch will be greatly diminished. There will be an optional dispatch timeout, and some other optional features that ensure all load requests eventually complete. See Project plans for upcoming features and ideas.

Additional features

  • Initial release is a feature-complete port of the reference implementation (only change being Manual dispatching).
  • See Project plans for upcoming features and ideas.

Let's get started!

Installing

No more talking. Let's install the vertx-dataloader dependency and look at some actual code!

Building

Using

JavaDoc

Project plans

Current releases

  • Not yet released

Known issues

  • ** Work in progress..**
  • Not yet production-ready as of yet, still porting tests that may uncover bugs.

Upcoming features

Future ideas

Other information sources

Contributing

All your feedback and help to improve this project is very welcome. Please create issues for your bugs, ideas and enhancement requests, or better yet, contribute directly by creating a PR.

When reporting an issue, please add a detailed instruction, and if possible a code snippet or test that can be used as a reproducer of your problem.

When creating a pull request, please adhere to the Vert.x coding style where possible, and create tests with your code so it keeps providing an excellent test coverage level. PR's without tests may not be accepted unless they only deal with minor changes.

Acknowledgements

This library is entirely inspired by the great works of Lee Byron and Nicholas Schrock from Facebook whom I like to thank, and especially @leebyron for taking the time and effort to provide 100% coverage on the codebase. A set of tests which I also ported.

Licensing

This project vertx-dataloader is licensed under the Apache Commons v2.0 license.

Copyright © 2016 Arnold Schrijver and other contributors

About

A Java 8 port of Facebook DataLoader

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Java 100.0%