Tuhin Subhra Mandal
Tuhin Subhra Mandal

Reputation: 523

Vertx CompositeFuture

I am working on a solution where I am using vertx 3.8.4 and vertx-mysql-client 3.9.0 for asynchronous database calls.

Here is the scenario that I have been trying to resolve, in a proper reactive manner.

I have some mastertable records which are in inactive state. I run a query and get the list of records from the database.

This I did like this :

Future<List<Master>> locationMasters = getInactiveMasterTableRecords ();

 locationMasters.onSuccess (locationMasterList -> {

            if (locationMasterList.size () > 0) {
                uploadTargetingDataForAllInactiveLocations(vertx, amazonS3Utility, 
                 locationMasterList);
            }
        });

Now in uploadTargetingDataForAllInactiveLocations method, i have a list of items.

What I have to do is, I need to iterate over this list, for each item, I need to download a file from aws, parse the file and insert those data to db.

I understand the way to do it using CompositeFuture.

Can someone from vertx dev community help me with this or with some documentation available ?

I did not find good contents on this by googling.

Upvotes: 2

Views: 539

Answers (1)

Francesco
Francesco

Reputation: 95

I'm answering this as I was searching for something similar and I ended up spending some time before finding an answer and hopefully this might be useful to someone else in future.

I believe you want to use CompositeFuture in vertx only if you want to synchronize multiple actions. That means that you either want an action to execute in the case that either all your other actions on which your composite future is built upon succeed or at least one of the action on which your composite future is built upon succeed. In the first case I would use CompositeFuture.all(List<Future> futures) and in the second case I would use CompositeFuture.any(List<Future> futures).

As per your question, below is a sample code where a list of item, for each item we run an asynchronous operation (namely downloadAnProcessFile()) which returns a Future and we want to execute an action doAction() in the case that all the async actions succeeded:

    List<Future> futures = new ArrayList<>();
    locationMasterList.forEach(elem -> {
        Promise<Void> promise = Promise.promise();
        futures.add(promise.future());
        Future<Boolean> processStatus = downloadAndProcessFile(); // doesn't need to be boolean
        processStatus.onComplete(asyncProcessStatus -> {
            if (asyncProcessStatus.succeeded()){
                // eventually do stuff with the result
                promise.complete();
            } else {
                promise.fail("Error while processing file whatever");
            }
        });
    });

    CompositeFuture.all(futures).onComplete(compositeAsync -> {
        if (compositeAsync.succeeded()){
            doAction();   // <-- here do what you want to do when all future complete
        } else {
            // at least 1 future failed
        }
    });

This solution is probably not perfect and I suppose can be improved but this is what I found works for me. Hopefully will work for someone else.

Upvotes: 1

Related Questions