Asynchronous Processing in Java with Promises
Tags: java, lang, tutorial
Published: 2019-10-24 10:54:47

---
title: Asynchronous Processing in Java with Promises
published: true
description: Promise-based asynchronous processing in Java
tags: #java #lang #tutorial
---

The [Reactive Toolbox Core](https://github.com/siy/reactive-toolbox-core) library implements __Promise__-based asynchronous processing model somewhat similar (but not identical) to one implemented by ECMAScript 2015. 

Probably main difference is that `Promise` implemented by the library has only two states (`pending` and `resolved`) as opposed to three states in ECMAScript (`pending`, `resolved` and `rejected`). This difference is caused by the need for ECMASCript to implement error handling (hence third `rejected` state), while [Reactive Toolbox Core](https://github.com/siy/reactive-toolbox-core) uses [`Result<T>`-based error handling model](https://dev.to/siy/consistent-error-propagation-and-handling-in-java-158j) and does not need separate state for error. 

The need to support only two states significantly simplifies implementation. The `Promise` implemented in library is much simpler than, for example, `CompletableFuture` and much more lightweight. This approach also enables convenient handling of complex interaction scenarios with fluent and transparent syntax.

Let's look into this implementation little bit deeper. 

Promises can be created in both, pending and resolved states:

```java
final var pendigPromise = Promise.<Integer>promise();
final var resolvedPromise = Promise.<Integer>fulfilled(123);

```
Only first resolution is accepted and used as `Promise` instance result. All subsequent attempts to resolve promise will be ignored.

User can attach actions to promise. Those actions will be executed once promise will be resolved:

```java
final var holder = new AtomicInteger(-1);
final var promise = Promise.<Integer>promise()
                              .onSuccess(holder::set);
```
If then we call `promise.ok(1)` instance will be resolved and attached action executed. Attached actions are executed only once. If instance is already resolved by the moment when new action is attached, then action is executed immediately, in the context of calling thread. If instance is not yet resolved, then attached actions will be executed in the context of thread where promise is resolved.

The `Promise` has built-in scheduler which is tuned for large number of small and short tasks, which don't block. This scheduler can be used to run some action on promise asynchronously, perform resolution of promise asynchronously or schedule action on promise once specified timeout is expired. Timeouts are implemented with very small overhead and without any additional threads.

More examples:

```java
// create instance and immediately invoke code which uses this instance
final var promise = Promise.<JWT>promise(p -> p.resolve(service.createNewToken(user)))

// Set promise processing timeout
final var promise = Promise.<User>promise()
                               .when(Timeout.timeout(30).seconds(), Errors.TIMEOUT::asFailure);

// Resolve promise asynchronously, so all attached actions will be run in other thread
promise.asyncResolve(Result.success("ok"));

```
Sometimes it is necessary to make a transformation of received result before passing it further. For this purpose `Promise` has method `map()`:

```java
final Promise<String> promise = service.promiseRandomInteger()
                                       .map(Objects::toString);

```

Now it worth to look at more complex scenarios. 

##### `Promise.any()` and `Promise.anySuccess()`

Sometimes it is necessary to receive at least one response from different services. If any response is fine, then static `Promise.any()` can be used:

```java
final Promise<Integer> promise = Promise.any(service1.promiseInteger(),
                                             service2.promiseInteger());

```
First resolved promise will be returned as result, regardless if it was success or failure. But in most cases only successful result counts, then following method will help:
```java
final Promise<Integer> promise = 
         Promise.anySuccess(service1.promiseInteger(),
                            service2.promiseInteger());
```
In this case promise will be resolved as failure only if all promises will be resolved to failure. 

Another important property of this method is that it will cancel (i.e. resolve with special type of failure) all remaining pending promises once success is obtained.

##### `Promise.all()`

Quite often it is necessary to obtain several results before doing further processing. The set of static `Promise.all()` method serve exactly this purpose - resulting promise is resolved to success only when all passed promises are resolved to success. Successful result in this case returned as [`Tuple`](https://dev.to/siy/the-power-of-tuples-2cf4):

```java
   final Promise<Tuple3<Integer, String, UUID>> promise = 
            Promise.all(integerService.promiseInteger(),
                        stringService.promiseString(),
                        uuidService.promiseUuid());

```
Sometimes it is necessary to obtain some intermediate values and then pass them to yet another service, which will calculate result. In other words, this is the case of dependent calls which return promises. For this purpose library provided dedicated method:

##### `Promise.chainMap()`

Example below illustrates use of this method:

```java
    private ArticleService articleService;
    private TopicService topicService;
    private UserService userService;

    public Promise<List<Article>> userFeedHandler(final User.Id userId) {
        return all(topicService.topicsByUser(userId, Order.ANY),
                   userService.followers(userId))
                .chainMap(tuple -> tuple.map((topics, users) -> articleService.userFeed(map(topics, Topic::id), map(users, User::id))))
                .when(timeout(30).seconds(), failure(Errors.TIMEOUT));
    }
```
Let's look deeper into this example. First of all, `Promise.all()` is called to obtain results from `topicService` and `userService`. When these services resolve their promises with success, then `articleService` is invoked with transformed values received from first two calls. Finally, timeout is configured for returned promise, so even if there will be any issues, final promise will be resolved with timeout error.

All this complex processing with all relevant error handling is just one line of code.

#### Summary
The __Promise__-based asynchronous processing being combined with other functional programming techniques is a very powerful and expressive tool. It allows convenient expression of complex processing while keeping code clean and easy to read and write. Overall application of FP-style to Java enables creating modern applications which are convenient to create, extend, test and maintain.

#### Afterword
The [Reactive Toolbox Core](https://github.com/siy/reactive-toolbox-core) is still work in progress. It requires a lot of effort and I realize that the whole project is way bigger than one person can accomplish in reasonable time. So, those who want to participate are welcome to join project. Comments, ideas, suggestions are welcome as well.