Reakt is reactive interfaces for Java which includes: The emphasis is on defining interfaces that enable lambda expressions, and fluent APIs for asynchronous programming for Java. Note: This mostly just provides the interfaces not the implementations. There are some starter implementations but the idea is that anyone can implement this. It is all about interfaces. There will be adapters for Vertx, RxJava, Reactive Streams, etc. There is support for Guava Async (used by Cassandra) and the QBit microservices lib. Czar Maker uses Reakt for its reactive leadership election. Have a question?Getting startedUsing from maven<dependency> <groupId>io.advantageous</groupId> <artifactId>reakt</artifactId> <version>2.0.0.RELEASE</version> </dependency> Using from gradlecompile 'io.advantageous:reakt:2.0.0.RELEASE' Fluent Promise APIPromise<Employee> promise = promise() .then(e -> saveEmployee(e)) .catchError(error -> logger.error("Unable to lookup employee", error)); employeeService.lookupEmployee(33, promise); Or you can handle it in one line. Fluent Promise API example 2employeeService.lookupEmployee(33, promise().then(e -> saveEmployee(e)) .catchError(error -> logger.error( "Unable to lookup ", error)) ); Promises are both a callback and a Result; however, you can work with Callbacks directly. Using Result and callback directlyemployeeService.lookupEmployee(33, result -> { result.then(e -> saveEmployee(e)) .catchError(error -> { logger.error("Unable to lookup", error); }); }); In both of these examples, lookupEmployee would look like: Using Result and callback directlypublic void lookupEmployee(long employeeId, Callback<Employee> callback){...} You can use Promises to transform into other promises. Transforming into another type of promise using thenMapPromise<Employee> employeePromise = Promises.<Employee>blockingPromise(); Promise<Sheep> sheepPromise = employeePromise .thenMap(employee1 -> new Sheep(employee1.getId())); The You can find more examples in the reakt wiki. We also support working with streams. Promise conceptsThis has been adapted from this article on ES6 promises. A promise can be:
Java is not single threaded, meaning that two bits of code can run at the same time, so the design of this promise and streaming library takes that into account. There are three types of promises:
Replay promises are the most like their JS cousins. Replay promises are usually managed by the Reakt It is common to make async calls to store data in a NoSQL store or to call a remote REST interface or deal with a distributed cache or queue. Also Java is strongly typed so the library that mimics JS promises is going to look a bit different. We tried to use similar terminology where it makes sense. Events and Streams are great for things that can happen multiple times on the same object — keyup, touchstart, or event a user action stream from Kafka, etc. With those events you don't really care about what happened before when you attached the listener. But often times when dealing with services and data repositories, you want to handle a response with a specific next action, and a different action if there was an error or timeout from the responses. You essentially want to call and handle a response asynchronously and that is what promises allow. This is not our first time to bat with Promises. QBit has had Promises for a few years now. We just called them CallbackBuilders instead. We wanted to use more standard terminology and wanted to use the same terminology and modeling on projects that do not use QBit like Conekt, Vert.x, RxJava, and reactive streams. At their most basic level, promises are like event listeners except: A promise can only succeed or fail once. A promise cannot succeed or fail twice, neither can it switch from success to failure. Once it enters its BridgesReakt Guava Bridge which allows libs that use Guava async support to now have a modern Java feel. Cassandra Reakt exampleregister(session.executeAsync("SELECT release_version FROM system.local"), promise().thenExpect(expected -> gui.setMessage("Cassandra version is " + expected.get().one().getString("release_version")) ).catchError(error -> gui.setMessage("Error while reading Cassandra version: " + error.getMessage()) ) ); QBit 1 ships with a bridge and QBit 2will use Reakt as its primary reactive callback mechanism. Conekt, a slimmed down fork of Vert.x, will also use Reakt. See QBit microservices lib for more details. See our wiki for more details on Reakt. Further reading |