I would like to make REST call to the DynamoDB asynchronously using CompletableFuture
and method is provided:
private CompletableFuture<UpdateItemResult> updateDynamodbAsync(UpdateItemRequest request) {
return CompletableFuture.supplyAsync(() -> {
UpdateItemResult result = amazonDynamoDBClient.updateItem(request);
return result;
});
}
The execution of the code is provided below:
UpdateItemResult result = null;
CompletableFuture<UpdateItemResult> updateItemResultCompletableFuture = updateDynamodbAsync(updateItemRequest);
while (true) {
if (updateItemResultCompletableFuture.isDone()) {
result = updateItemResultCompletableFuture.get(3000, TimeUnit.MILLISECONDS);
break;
}
}
The while
loop is blocking until the request is completed and I think this blocks the process. Is the code is still asynchronous and if not how can I improve it?
Secondly, I would handle errors separately with a null check:
if (result == null) {
LOGGER.debug("The update operation in the DynamoDB is not sucessful .......");
return dbPresistenceResponseMap;
}
Is it fine?
CodePudding user response:
You while(true)
loop can be simplified to updateItemResultCompletableFuture.join()
or .get()
.
Of course both with the while and join would block the process, so even though you DynamoDB would be made asynchronously, you wouldn’t benefit from it. The right way to keep the execution asynchronous would be to chain calls on the future with one of the then…()
methods.
For example, your error handling could be done with
return updateItemResultCompletableFuture.thenApply(result -> {
if (result == null) {
LOGGER.debug("The update operation in the DynamoDB is not sucessful .......");
return dbPresistenceResponseMap;
}
return /* success result */;
}
If the caller also needs to perform something with that result, you would have to return a CompletableFuture
as well (hence the return
I put on the first line here). This will allow it to chain more calls.
As a side note, using supplyAsync()
without providing an Executor
will make your call run on the common ForkJoinPool
, which is designed to run CPU-bound tasks. Since this is an I/O operation, you should provide your own Executor
.
Finally, I am not familiar with AWS, but note that DynamoDB also has an async client, you should probably use it.