novafluff
novafluff

Reputation: 911

asynchronous programming in java with void methods

I have never really worked with asynchronous programming in Java and got very confused on the practice is the best one.

I got this method

public static CompletableFuture<Boolean> restoreDatabase(){
   DBRestorerWorker dbWork = new DBRestorerWorker();
   dbWork.run();
   return "someresult" ;
}

then this one which calls the first one

@POST
@Path("{backupFile}")
@Consumes("application/json")
public void createOyster(@PathParam("backupFile") String backupFile) {
  RestUtil.restoreDatabase("utv_johan", backupFile);
  //.then somemethod()
  //.then next method()
}

What I want to do is first call the restoreDatabase() method which calls dbWork.run() (which is an void method) and when that method is done I want createOyster to do the next one and so forth until I have done all the steps needed. Someone got a guideline were to start with this. Which practice is best in today's Java?

Upvotes: 2

Views: 5893

Answers (2)

Amit Tyagi
Amit Tyagi

Reputation: 320

You can use AsyncResponse:

import javax.ws.rs.container.AsyncResponse;


public static CompletableFuture<String> restoreDatabase(){
   DBRestorerWorker dbWork = new DBRestorerWorker();
   dbWork.run();
   return CompletableFuture.completedFuture("someresult");
}

and this

@POST
@Path("{backupFile}")
@Consumes("application/json")
public void createOyster(@PathParam("backupFile") String backupFile,
@Suspended AsyncResponse ar) {
  RestUtil.restoreDatabase("utv_johan", backupFile)
  .thenCompose(result -> doSomeAsyncCall())
  .thenApply(result -> doSomeSyncCall())
  .whenComplete(onFinish(ar))
  //.then next method()
}

utility function to send response

static <R> BiConsumer<R, Throwable> onFinish(AsyncResponse ar) {
  return (R ok, Throwable ex) -> {
    if (ex != null) {
      // do something with exception  
      ar.resume(ex);
    }
    else {
      ar.resume(ok);
    }
  };
}

Upvotes: 1

Laksitha Ranasingha
Laksitha Ranasingha

Reputation: 4507

As you already use CompletableFuture, you may build your async execution pipeline like.

CompletableFuture.supplyAsync(new Supplier<String>() {
            @Override
            public String get() {
                DBRestorerWorker dbWork = new DBRestorerWorker();
                dbWork.run();
                return "someresult";
            };
        }).thenComposeAsync((Function<String, CompletionStage<Void>>) s -> {
            CompletableFuture<String> future = new CompletableFuture<>();
            try{
                //createOyster
                future.complete("oyster created");
            }catch (Exception ex) {
                future.completeExceptionally(ex);
            }
            return null;
        });

As you could see, You can call thenComposeAsync or thenCompose to build a chain of CompletionStages and perform tasks using results of the previous step or make Void if you don't have anything to return.

Here's a very good guide

Upvotes: 1

Related Questions