-
Notifications
You must be signed in to change notification settings - Fork 8
Promises.any
We have any
support to Promises
. You can create a Promise
from other promises.
If any of the child promises async return, then the parent promise async returns.
Promise.any(promises...) method returns a promise that resolves as soon as one of promises resolves. It will ignore errors from any of the other promises as long as they don’t all error. It is similar but different than Promises.race from JavaScript. Many JavaScript libs have an any equiv. to Promises.any. Promise.race does not seem as useful as Promise.any, but we might add Promise.race as well.
We also have all
support.
Both the reactor and the static class has Promises.all and Promises.any.
//Send to the queue and two tables in Cassandra at the same time,
// wait until one of the succeed and then resolve the original call.
reactor.any(Duration.ofSeconds(30),
messageQueue.sendToQueue(todo)
.catchError(error -> logger.error("Send to queue failed", error))
.thenSafe(enqueued -> logger.info("Sent to queue")),
//Call to save Todo in two table, don't respond until both calls come back.
reactor.all(Duration.ofSeconds(15),
futureToPromise( // First call to cassandra.
session.executeAsync(insertInto("Todo")...)
).catchError(error -> recordCassandraError("add.todo", error))
.thenSafe(resultSet -> handleResultFromAdd(...)),
futureToPromise( // Second call to cassandra.
session.executeAsync(insertInto("TodoLookup")...)
).catchError(error -> recordCassandraError("add.lookup", error))
.thenSafe(resultSet -> handleResultFromAdd(...)))//end all
).catchError(returnPromise::reject)
.then(v -> returnPromise.resolve(true)).invoke();
/** Employe service. */
EmployeeService employeeService = ...
/* Promises that expects an employee. */
Promise<Employee> promise1 = Promises.promise();
Promise<Employee> promise2 = Promises.promise();
/* Promise that returns when any employees are returned. */
final Promise<Void> promise = Promises.any(promise1, promise2);
promise.then(nil -> System.out.println("DONE!"));
assertFalse("Not done yet", promise.complete());
/** Call service. */
employeeService.loadEmployee("id1", promise2);
/** Wait some time. */
//...
assertTrue(promise.complete());
assertTrue(promise.success());
We also support anyReplayPromise
and anyBlockingPromise
.
A replay promise is a promise that executes on the caller's thread not the callee.
A blocking promise is a promise that blocks until the callback returns.
We only recommend using blocking promises for legacy integration and testing.
####Any API in Promises
...
public interface Promises {
/**
* Any promises must complete.
*
* @param promises promises
* @return return containing promise
*/
static Promise<Void> any(final Promise<?>... promises) {
return new AnyPromise(promises);
}
/**
* All promises must complete.
*
* @param promises promises
* @param <T> types of promise
* @return return containing promise
*/
static <T> Promise<Void> any(final List<Promise<T>> promises) {
return new AnyPromise(promises.toArray(new Promise[promises.size()]));
}
/**
* Any promises must complete.
*
* @param promises promises
* @return return containing promise that is blocking.
*/
static Promise<Void> anyBlocking(final Promise<?>... promises) {
return new AnyBlockingPromise(promises);
}
/**
* Any promises must complete.
*
* @param promises promises
* @param <T> types of promise
* @return return containing promise that is blocking.
*/
static <T> Promise<Void> anyBlocking(final List<Promise<T>> promises) {
return new AnyBlockingPromise(promises.toArray(new Promise[promises.size()]));
}
/**
* Any promises must complete.
*
* @param timeout timeout
* @param time time
* @param promises promises
* @return returns replay promise so promise can be replayed in caller's thread.
*/
static ReplayPromise<Void> anyReplay(final Duration timeout, long time,
final Promise<?>... promises) {
return new AnyReplayPromise(timeout, time, promises);
}
/**
* Any promises must complete.
*
* @param timeout timeout
* @param time time
* @param promises promises
* @param <T> types of promise
* @return returns replay promise so promise can be replayed in caller's thread.
*/
static <T> ReplayPromise<Void> anyReplay(final Duration timeout, long time,
final List<Promise<T>> promises) {
return new AnyReplayPromise(timeout, time, promises.toArray(new Promise[promises.size()]));
}
/**
* Any promises must complete.
*
* @param timeout timeout
* @param promises promises
* @return returns replay promise so promise can be replayed in caller's thread.
*/
static ReplayPromise<Void> anyReplay(final Duration timeout, final Promise<?>... promises) {
return anyReplay(timeout, System.currentTimeMillis(), promises);
}
/**
* Any promises must complete.
*
* @param timeout timeout
* @param promises promises
* @param <T> types of promise
* @return returns replay promise so promise can be replayed in caller's thread.
*/
static <T> ReplayPromise<Void> anyReplay(final Duration timeout, final List<Promise<T>> promises) {
return anyReplay(timeout, System.currentTimeMillis(), promises.toArray(new Promise[promises.size()]));
}
@Test
public void testAnyBlocking() throws Exception {
TestService testService = new TestService();
Promise<Employee> promise1 = Promises.promise();
Promise<Employee> promise2 = Promises.promise();
final Promise<Void> promise = Promises.anyBlocking(promise1, promise2);
assertFalse(promise.complete());
testService.async(promise2);
assertTrue(promise.success());
}
@Test
public void testAnyReplay() throws Exception {
TestService testService = new TestService();
Promise<Employee> promise1 = Promises.promise();
Promise<Employee> promise2 = Promises.promise();
final ReplayPromise<Void> promise = Promises.anyReplay(Duration.ofMillis(1000),
promise1, promise2);
assertFalse(promise.complete());
testService.async(promise2);
for (int index = 0; index < 10; index++) {
promise.check(System.currentTimeMillis());
if (promise.complete()) break;
Thread.sleep(10);
}
assertTrue(promise.complete());
assertTrue(promise.success());
}
public static class TestService {
public void simple(Callback<Employee> callback) {
callback.reply(new Employee("Rick"));
}
public void async(final Callback<Employee> callback) {
new Thread(() -> {
callback.reply(new Employee("Rick"));
}).start();
}
public void asyncTimeout(final Callback<Employee> callback) {
new Thread(() -> {
try {
Thread.sleep(10_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
callback.reply(new Employee("Rick"));
}).start();
}
public void asyncError(final Callback<Employee> callback) {
new Thread(() -> {
callback.reject("Rick");
}).start();
}
public void error(Callback<Employee> callback) {
callback.reject("Error");
}
public void exception(Callback<Employee> callback) {
callback.reject(new IllegalStateException("Error"));
}
}
Java Promises
- Promise
- Promise then*() and catchError()
- Promise thenMap()
- Promise all()
- Promise any()
- Blocking Promise
- Invokable Promise
- Reactor Replay Promises
Reactor, Stream, Results
- QBit Reactive Microservices
- Reakt Reactive Java
- Reakt Guava Bridge
- QBit Extensions
- Elekt Consul Leadership election
- Elekt Leadership election
- Reactive Microservices
What is Microservices Architecture?
QBit Java Micorservices lib tutorials
The Java microservice lib. QBit is a reactive programming lib for building microservices - JSON, HTTP, WebSocket, and REST. QBit uses reactive programming to build elastic REST, and WebSockets based cloud friendly, web services. SOA evolved for mobile and cloud. ServiceDiscovery, Health, reactive StatService, events, Java idiomatic reactive programming for Microservices.
Reactive Programming, Java Microservices, Rick Hightower
Java Microservices Architecture
[Microservice Service Discovery with Consul] (http://www.mammatustech.com/Microservice-Service-Discovery-with-Consul)
Microservices Service Discovery Tutorial with Consul
[Reactive Microservices] (http://www.mammatustech.com/reactive-microservices)
[High Speed Microservices] (http://www.mammatustech.com/high-speed-microservices)
Reactive Microservices Tutorial, using the Reactor
QBit is mentioned in the Restlet blog
All code is written using JetBrains Idea - the best IDE ever!
Kafka training, Kafka consulting, Cassandra training, Cassandra consulting, Spark training, Spark consulting
Java Promises
- Promise
- Promise then*() and catchError()
- Promise thenMap()
- Promise all()
- Promise any()
- Blocking Promise
- Invokable Promise
- Reactor Replay Promises
Callback, and async Results
Reactor, Stream and Stream Result
Expected & Circuit Breaker
Scala Akka and Reakt