How to test asynchronous method - java

I need to asynchronously fetch some data from DB, and then synchronously update currently cached data, with the one that was fetched.
At the moment my code looks like this:
#Asynchronous
public void fetchData() {
CompletableFuture.supplyAsync(() -> {
//Do some logic to fetch data
return fetchedData;
}).thenAccept(fetchedData -> updateCache(fetchedData));
}
My problem is that when I call this method in my tests, it instantly goes to thenAccept but fetchedData is empty. I've tried to change my method, and return CompletableFuture<List<Data>>, and call fetchData().join() in tests. It worked fine, but first - my app wouldn't build, since #Asynchronous need to return Future or void, and I don't think changing method just to test it is a good idea.
I've heard about Await library, but can not use it in current project.
I'am also not sure, if #Asynchronous is needed in my case? If I'm not mistaken, CompletableFuture should run in own thread by default?

Jacek, I think #Asynchronous annotation is not required. You can use the pure form of completable future. I provide below the sample code based upon the code you have provided.
public String getInfoFromDB() {
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Data from DB";
}
public void updateCache(String dataFromDB) {
System.out.println("Data from D : " + dataFromDB);
System.out.println("Doing some operations with data from DB");
}
public void fetchData() {
CompletableFuture cf =
CompletableFuture.supplyAsync(() -> getInfoFromDB())
.thenAccept(dataFromDB -> updateCache(dataFromDB));
cf.join();
}

You can use this useful library: awaitility

Related

Return autocloseable object inside a CompletableFuture and use it in whenComplete

I want to return an autocloseable object inside a CompletableFuture and use it in whenComplete without going to close it manually later.
This is the code that I've tried, but of course it won't work because it closes automatically when I return Jedis object. I haven't got any other ideas.
#Override
public CompletableFuture<Jedis> execute() {
if(!isServiceActive()) return CompletableFuture.completedFuture(null);
return CompletableFuture.supplyAsync(() -> {
try (Jedis jedis = pool.getResource()) {
return jedis;
} catch (RuntimeException e) {
logger.severe("Impossibile ottenere una nuova risorsa Jedis!", e);
throw new CompletionException(e);
}
}, executor);
}
In general, this is not possible; CompletableFuture is not designed for this. As you've noted, you can't close the resource before completing the future, because then it will be closed before any consumers get to act on it. That means the consumer will have to be responsible for closing the resource.
However, if your goal is to only need that Jedis instance in the one whenComplete call, then perhaps there is an alternative solution. Either modify execute() or create a new method that looks something like the following:
<T> CompletableFuture<T> execute(Function<? super Jedis, ? extends T> func) {
if (!isServiceActive()) return CompletableFuture.completedFuture(null);
return CompletableFuture.supplyAsync(() -> {
try (Jedis jedis = pool.getResource()) {
return func.apply(jedis);
} catch (Exception ex) {
// log exception
throw new CompletionException(ex);
}
}), executor);
}
The Jedis instance is closed by the time the future completes, but it still lets you do the needed work in the Function implementation. Using it would look like:
execute(jedis -> {
// use Jedis instance
return result;
})
.whenComplete((result, error) -> {
if (error != null) {
// process error
} else {
// process result
}
});
Though I don't know if your code can be modified to use this approach, as I notice your execute() method is an override (whether from a class/interface you control, I don't know). But even if you can't modify execute() directly or supply an overload feasibly, you might still be able to create a utility method that does something similar to the above.

Difference between DeferedResult and CompletableFeature

I've been developing Rest API's in Java. I want to convert them it into Async. The Two options I see is DeferredResult and CompletableFeature.
I don't seem to be find the difference between these two, and when to chose over another.
Any real time examples would be appreciated.
DeferredResult is spring class and it is just a container of the result (as its name implies) so we need to explicitly use some kind of thread pool (ForkJoinPool for example) to run our processing asynchronously. CompletableFuture is part of java.util.concurrent and allow to run the processing asynchronously. It implements Future and basically have the ability to compose, combine and execute asynchronous computation steps.
Simple example of both options:
#GetMapping(value = "/deferredResult")
public DeferredResult<Boolean> useDeferredResult() {
DeferredResult<Boolean> deferredResult = new DeferredResult<>();
deferredResult.onCompletion(() -> logResult((Boolean)deferredResult.getResult()));
ForkJoinPool.commonPool().submit(() -> {
deferredResult.setResult(processRequest());
});
return deferredResult;
}
#GetMapping(value = "/completableFuture")
public CompletableFuture<Boolean> useCompletableFuture() {
return CompletableFuture.supplyAsync(this::processRequest)
.thenApplyAsync(this::logResult);
}
private boolean logResult(Boolean result) {
System.out.println("Result: " + result);
return true;
}
private boolean processRequest() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
return true;
}
Notes:
By default, Spring will execute the CompletableFuture actions by
ForkJoinPool (can be configured).
In the case of DeferredResult, the logResult will be executed by the servlet container (for example Tomcat) worker thread - not nessecrally the one got the request at the beginning.
You can (while I don't see any
reason to) run processing asynchronously with CompletableFuture and
return DeferredResult.
With DeferredResult you can register more callbacks, like onCompleted - For example onError, etc. See here.
CompletableFuture has a lot options to compose actions. See here.
IMHO, CompletableFuture is more elegant and has more capabilities.
Also, here you have a working example project.

Calling multiple methods asynchronously and updating an object [duplicate]

I've been looking at Go's goroutines lately and thought it would be nice to have something similar in Java. As far as I've searched the common way to parallelize a method call is to do something like:
final String x = "somethingelse";
new Thread(new Runnable() {
public void run() {
x.matches("something");
}
}).start();
Thats not very elegant. Is there a better way of doing this? I needed such a solution in a project so I decided to implement my own wrapper class around a async method call.
I published my wrapper class in J-Go. But I don't know if it is a good solution. The usage is simple:
SampleClass obj = ...
FutureResult<Integer> res = ...
Go go = new Go(obj);
go.callLater(res, "intReturningMethod", 10); //10 is a Integer method parameter
//... Do something else
//...
System.out.println("Result: "+res.get()); //Blocks until intReturningMethod returns
or less verbose:
Go.with(obj).callLater("myRandomMethod");
//... Go away
if (Go.lastResult().isReady()) //Blocks until myRandomMethod has ended
System.out.println("Method is finished!");
Internally I'm using a class that implements Runnable and do some Reflection work to get the correct method object and invoking it.
I want some opinion about my tiny library and on the subject of making async method calls like this in Java. Is it safe? Is there already a simplier way?
I just discovered that there is a cleaner way to do your
new Thread(new Runnable() {
public void run() {
//Do whatever
}
}).start();
(At least in Java 8), you can use a lambda expression to shorten it to:
new Thread(() -> {
//Do whatever
}).start();
As simple as making a function in JS!
Java 8 introduced CompletableFuture available in package java.util.concurrent.CompletableFuture, can be used to make a asynch call :
CompletableFuture.runAsync(() -> {
// method call or code to be asynch.
});
You may wish to also consider the class java.util.concurrent.FutureTask.
If you are using Java 5 or later, FutureTask is a turnkey implementation of "A cancellable asynchronous computation."
There are even richer asynchronous execution scheduling behaviors available in the java.util.concurrent package (for example, ScheduledExecutorService), but FutureTask may have all the functionality you require.
I would even go so far as to say that it is no longer advisable to use the first code pattern you gave as an example ever since FutureTask became available. (Assuming you are on Java 5 or later.)
i don't like the idea of using Reflection for that.
Not only dangerous for missing it in some refactoring, but it can also be denied by SecurityManager.
FutureTask is a good option as the other options from the java.util.concurrent package.
My favorite for simple tasks:
Executors.newSingleThreadExecutor().submit(task);
little bit shorter than creating a Thread (task is a Callable or a Runnable)
You can use the Java8 syntax for CompletableFuture, this way you can perform additional async computations based on the result from calling an async function.
for example:
CompletableFuture.supplyAsync(this::findSomeData)
.thenApply(this:: intReturningMethod)
.thenAccept(this::notify);
More details can be found in this article
You can use #Async annotation from jcabi-aspects and AspectJ:
public class Foo {
#Async
public void save() {
// to be executed in the background
}
}
When you call save(), a new thread starts and executes its body. Your main thread continues without waiting for the result of save().
You can use Future-AsyncResult for this.
#Async
public Future<Page> findPage(String page) throws InterruptedException {
System.out.println("Looking up " + page);
Page results = restTemplate.getForObject("http://graph.facebook.com/" + page, Page.class);
Thread.sleep(1000L);
return new AsyncResult<Page>(results);
}
Reference: https://spring.io/guides/gs/async-method/
Java also provides a nice way of calling async methods. in java.util.concurrent we have ExecutorService that helps in doing the same. Initialize your object like this -
private ExecutorService asyncExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
and then call the function like-
asyncExecutor.execute(() -> {
TimeUnit.SECONDS.sleep(3L);}
You can use AsyncFunc from Cactoos:
boolean matches = new AsyncFunc(
x -> x.matches("something")
).apply("The text").get();
It will be executed at the background and the result will be available in get() as a Future.
It's probably not a real solution, but now - in Java 8 - You can make this code look at least a little better using lambda expression.
final String x = "somethingelse";
new Thread(() -> {
x.matches("something");
}
).start();
And You could even do this in one line, still having it pretty readable.
new Thread(() -> x.matches("something")).start();
This is not really related but if I was to asynchronously call a method e.g. matches(), I would use:
private final static ExecutorService service = Executors.newFixedThreadPool(10);
public static Future<Boolean> matches(final String x, final String y) {
return service.submit(new Callable<Boolean>() {
#Override
public Boolean call() throws Exception {
return x.matches(y);
}
});
}
Then to call the asynchronous method I would use:
String x = "somethingelse";
try {
System.out.println("Matches: "+matches(x, "something").get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
I have tested this and it works. Just thought it may help others if they just came for the "asynchronous method".
There is also nice library for Async-Await created by EA: https://github.com/electronicarts/ea-async
From their Readme:
With EA Async
import static com.ea.async.Async.await;
import static java.util.concurrent.CompletableFuture.completedFuture;
public class Store
{
public CompletableFuture<Boolean> buyItem(String itemTypeId, int cost)
{
if(!await(bank.decrement(cost))) {
return completedFuture(false);
}
await(inventory.giveItem(itemTypeId));
return completedFuture(true);
}
}
Without EA Async
import static java.util.concurrent.CompletableFuture.completedFuture;
public class Store
{
public CompletableFuture<Boolean> buyItem(String itemTypeId, int cost)
{
return bank.decrement(cost)
.thenCompose(result -> {
if(!result) {
return completedFuture(false);
}
return inventory.giveItem(itemTypeId).thenApply(res -> true);
});
}
}

How to chain non-blocking action in CompletionStage.exceptionally

I am writing a Play2 application service method in Java that should do the following. Asynchronously call method A, and if that fails, asynchronously call method B.
To illustrate assume this interface for the backend called by the service:
public interface MyBackend {
CompletionStage<Object> tryWrite(Object foo);
CompletionStage<Object> tryCleanup(Object foo);
}
So in my service method, I want to return a Future that can complete with these:
Success of tryWrite completed
Fail of tryWrite and Success of tryCleanup completed and failing with exception of tryWrite()
(Note: Of course tryWrite() could do any cleanup itself, this is a simplified example to illustrate a problem)
The implementation of a service calling the backend like this seems difficult to me because the CompletionStage.exceptionally() method does not allow Composing.
Version 1:
public class MyServiceImpl {
public CompletionStage<Object> tryWriteWithCleanup(Object foo) {
CompletionStage<Object> writeFuture = myBackend.tryWrite(foo)
.exceptionally((throwable) -> {
CompletionStage<Object> cleanupFuture = myBackend.tryCleanup(foo);
throw new RuntimeException(throwable);
});
return writeFuture;
}
}
So version 1 calls tryCleanup(foo) in a non-blocking way, but the CompletionStage returned by tryWriteWithCleanup() will not wait for cleanupFuture to complete. How to change this code to return a future from the service that would also wait for completion of cleanupFuture?
Version 2:
public class MyServiceImpl {
public CompletionStage<Object> tryWriteWithCleanup(Object foo) {
final AtomicReference<Throwable> saveException = new AtomicReference<>();
CompletionStage<Object> writeFuture = myBackend
.tryWrite(foo)
.exceptionally(t -> {
saveException.set(t);
// continue with cleanup
return null;
})
.thenCompose((nil) -> {
// if no cleanup necessary, return
if (saveException.get() == null) {
return CompletableFuture.completedFuture(null);
}
return CompletionStage<Object> cleanupFuture = myBackend.tryCleanup(foo)
.exceptionally(cleanupError -> {
// log error
return null;
})
.thenRun(() -> {
throw saveException.get();
});
});
return writeFuture;
}
}
Version2 uses an external AtomicReference to store the failure, and makes the asynchronous second call in another thenCompose() block, if there was a failure.
All my other attempts to do so ended up so unwieldy that I don't want to paste them here.
Unfortunately CompletionStage/CompletableFuture does not provide exception handling API's with composition.
You can work around this though by relying on a handle() with a BiFunction that returns a CompletionStage. This will give you nested stages (CompletionStage<CompletionStage<Object>>) that you can the "unnest" using compose(identity()):
public CompletionStage<Object> tryWriteWithCleanup(Object foo) {
return myBackend.tryWrite(foo)
.handle((r, e) -> {
if (e != null) {
return myBackend.tryCleanup(foo)
.handle((r2, e2) -> {
// Make sure we always return the original exception
// but keep track of new exception if any,
// as if run in a finally block
if (e2 != null) {
e.addSuppressed(e2);
}
// wrapping in CompletionException behaves as if
// we threw the original exception
throw new CompletionException(e);
});
}
return CompletableFuture.completedFuture(r);
})
.thenCompose(Function.identity());
}
You may simply wait for the completion inside the handler:
public CompletionStage<Object> tryWriteWithCleanup(Object foo) {
return myBackend.tryWrite(foo).exceptionally(throwable -> {
myBackend.tryCleanup(foo).toCompletableFuture().join();
throw new CompletionException(throwable);
});
}
This will defer the completion of the result CompletionStage to the completion of the cleanup stage. Using CompletionException as wrapper will make the wrapping transparent to the caller.
However, it has some drawbacks. While the framework might utilize the thread while waiting or spawn a compensation thread, if it is a worker thread, the blocked thread might be the caller thread if the stage returned by tryWrite happens to be already completed when entering exceptionally. Unfortunately, there is no exceptionallyAsync method. You may use handleAsync instead, but it will complicate the code while still feeling like a kludge.
Further, exceptions thrown by the cleanup may shadow the original failure.
A cleaner solution may be a bit more involved:
public CompletionStage<Object> tryWriteWithCleanup(Object foo) {
CompletableFuture<Object> writeFuture = new CompletableFuture<>();
myBackend.tryWrite(foo).whenComplete((obj,throwable) -> {
if(throwable==null)
writeFuture.complete(obj);
else
myBackend.tryCleanup(foo).whenComplete((x,next) -> {
try {
if(next!=null) throwable.addSuppressed(next);
}
finally {
writeFuture.completeExceptionally(throwable);
}
});
});
return writeFuture;
}
This simply creates a CompletableFuture manually, allowing to control its completion, which will happen either directly by the action chained to tryWrite’s stage in the successful case, or by the action chained to the cleanup stage in the exceptional case. Note that the latter takes care about chaining a possible subsequent cleanup exception via addSuppressed.

How to asynchronously call a method in Java

I've been looking at Go's goroutines lately and thought it would be nice to have something similar in Java. As far as I've searched the common way to parallelize a method call is to do something like:
final String x = "somethingelse";
new Thread(new Runnable() {
public void run() {
x.matches("something");
}
}).start();
Thats not very elegant. Is there a better way of doing this? I needed such a solution in a project so I decided to implement my own wrapper class around a async method call.
I published my wrapper class in J-Go. But I don't know if it is a good solution. The usage is simple:
SampleClass obj = ...
FutureResult<Integer> res = ...
Go go = new Go(obj);
go.callLater(res, "intReturningMethod", 10); //10 is a Integer method parameter
//... Do something else
//...
System.out.println("Result: "+res.get()); //Blocks until intReturningMethod returns
or less verbose:
Go.with(obj).callLater("myRandomMethod");
//... Go away
if (Go.lastResult().isReady()) //Blocks until myRandomMethod has ended
System.out.println("Method is finished!");
Internally I'm using a class that implements Runnable and do some Reflection work to get the correct method object and invoking it.
I want some opinion about my tiny library and on the subject of making async method calls like this in Java. Is it safe? Is there already a simplier way?
I just discovered that there is a cleaner way to do your
new Thread(new Runnable() {
public void run() {
//Do whatever
}
}).start();
(At least in Java 8), you can use a lambda expression to shorten it to:
new Thread(() -> {
//Do whatever
}).start();
As simple as making a function in JS!
Java 8 introduced CompletableFuture available in package java.util.concurrent.CompletableFuture, can be used to make a asynch call :
CompletableFuture.runAsync(() -> {
// method call or code to be asynch.
});
You may wish to also consider the class java.util.concurrent.FutureTask.
If you are using Java 5 or later, FutureTask is a turnkey implementation of "A cancellable asynchronous computation."
There are even richer asynchronous execution scheduling behaviors available in the java.util.concurrent package (for example, ScheduledExecutorService), but FutureTask may have all the functionality you require.
I would even go so far as to say that it is no longer advisable to use the first code pattern you gave as an example ever since FutureTask became available. (Assuming you are on Java 5 or later.)
i don't like the idea of using Reflection for that.
Not only dangerous for missing it in some refactoring, but it can also be denied by SecurityManager.
FutureTask is a good option as the other options from the java.util.concurrent package.
My favorite for simple tasks:
Executors.newSingleThreadExecutor().submit(task);
little bit shorter than creating a Thread (task is a Callable or a Runnable)
You can use the Java8 syntax for CompletableFuture, this way you can perform additional async computations based on the result from calling an async function.
for example:
CompletableFuture.supplyAsync(this::findSomeData)
.thenApply(this:: intReturningMethod)
.thenAccept(this::notify);
More details can be found in this article
You can use #Async annotation from jcabi-aspects and AspectJ:
public class Foo {
#Async
public void save() {
// to be executed in the background
}
}
When you call save(), a new thread starts and executes its body. Your main thread continues without waiting for the result of save().
You can use Future-AsyncResult for this.
#Async
public Future<Page> findPage(String page) throws InterruptedException {
System.out.println("Looking up " + page);
Page results = restTemplate.getForObject("http://graph.facebook.com/" + page, Page.class);
Thread.sleep(1000L);
return new AsyncResult<Page>(results);
}
Reference: https://spring.io/guides/gs/async-method/
Java also provides a nice way of calling async methods. in java.util.concurrent we have ExecutorService that helps in doing the same. Initialize your object like this -
private ExecutorService asyncExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
and then call the function like-
asyncExecutor.execute(() -> {
TimeUnit.SECONDS.sleep(3L);}
You can use AsyncFunc from Cactoos:
boolean matches = new AsyncFunc(
x -> x.matches("something")
).apply("The text").get();
It will be executed at the background and the result will be available in get() as a Future.
It's probably not a real solution, but now - in Java 8 - You can make this code look at least a little better using lambda expression.
final String x = "somethingelse";
new Thread(() -> {
x.matches("something");
}
).start();
And You could even do this in one line, still having it pretty readable.
new Thread(() -> x.matches("something")).start();
This is not really related but if I was to asynchronously call a method e.g. matches(), I would use:
private final static ExecutorService service = Executors.newFixedThreadPool(10);
public static Future<Boolean> matches(final String x, final String y) {
return service.submit(new Callable<Boolean>() {
#Override
public Boolean call() throws Exception {
return x.matches(y);
}
});
}
Then to call the asynchronous method I would use:
String x = "somethingelse";
try {
System.out.println("Matches: "+matches(x, "something").get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
I have tested this and it works. Just thought it may help others if they just came for the "asynchronous method".
There is also nice library for Async-Await created by EA: https://github.com/electronicarts/ea-async
From their Readme:
With EA Async
import static com.ea.async.Async.await;
import static java.util.concurrent.CompletableFuture.completedFuture;
public class Store
{
public CompletableFuture<Boolean> buyItem(String itemTypeId, int cost)
{
if(!await(bank.decrement(cost))) {
return completedFuture(false);
}
await(inventory.giveItem(itemTypeId));
return completedFuture(true);
}
}
Without EA Async
import static java.util.concurrent.CompletableFuture.completedFuture;
public class Store
{
public CompletableFuture<Boolean> buyItem(String itemTypeId, int cost)
{
return bank.decrement(cost)
.thenCompose(result -> {
if(!result) {
return completedFuture(false);
}
return inventory.giveItem(itemTypeId).thenApply(res -> true);
});
}
}

Categories

Resources