2

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?

2
  • 1
    What exactly is your question? How to implement the restoreDatabase method? You can do return CompletableFuture.runAsync(new DBRestorerWorker()); (But that will return a CompletableFuture<Void> - not sure you how expect to get a Boolean from a void method.) Commented Mar 29, 2018 at 9:35
  • my question is how do i make sure that the dbWork.run() is done before the CreateOyster() method triggers the next method Commented Mar 29, 2018 at 9:37

2 Answers 2

1

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

Sign up to request clarification or add additional context in comments.

Comments

1

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);
    }
  };
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.