SlideShare a Scribd company logo
Leveraging CompletableFutures to handle
your query results asynchronously
David Gómez G.


Developer Advocate
Concurrency vs
Parallelism
Concurrency
Different type of tasks


Usually do some works while waiting for
other tasks to be completed.


Have the work finished before
Same type of tasks


Workload split between similar workers


Have the work finished before
Parallelism
@DGOMEZG
Java and Concurrency
Lots of tools since Java 1
Java has building blocks for Concurrency and parallelism since
Java 1.


Even when most desktop computers were single-core
@DGOMEZG
Threads
Very Expensive
Thread t = new Thread(task);

t.start();

t.join();

Easily forgotten
Blocking call
ThreadPools
@DGOMEZG
ThreadPools
@DGOMEZG
ThreadPools
@DGOMEZG
ThreadPools
@DGOMEZG
ThreadPools
@DGOMEZG
Since Java 5
Concurrency & parallelism support improved in Java 5


Lots of New Concurrency constructors


New concurrent-friendly Data Structures


Revisited and improved in Java 7, 8, 9 …


More coming up as part of loom project
@DGOMEZG
Running tasks
asynchronously
ExecutorService
And now we can submit tasks that return a result.


Executor Service, returns a Future<T>
@DGOMEZG
ExecutorService & Future<T>
ExecutorService executorService = Executors.newCachedThreadPool();

Future<String> taskResult = 

executorService.submit(longRunningTaskWithResult);
String s = taskResult.get();
Blocking call
ExecutorService & Future<T>
ExecutorService executorService = Executors.newCachedThreadPool();

Future<String> taskResult = 

executorService.submit(longRunningTaskWithResult);
while (!taskResult.isDone()) {

doSomethingElse();

}

String s = taskResult.get();

False while task is not cancelled
nor
fi
nished
Improving performance by doing
other tasks.
Running Multiple T
asks
List<Future<String
>
>
taskResults = new ArrayList
<
>
();

for (Callable<String> task : tasks) {

taskResults.add(executorService.submit(task));

}

for (Future<String> result : taskResults) {

processResult(result.get());

}

Bene
fi
t only between submitting
all tasks and getting the results
Running Heterogeneous T
asks
List<Future<String
>
>
taskResults = new ArrayList
<
>
();

for (Callable<String> task : tasks) {

taskResults.add(executorService.submit(task));

}

for (Future<String> result : taskResults) {

processResult(result.get());

}
 What if task1 is too slow
while task2 is fast?
What if we need the result of
task1 to submit task2?
(CompletionService returns
tasks in the order they are
fi
nished)
CompletableFuture
CompletableFuture<T>
Introduced in Java8


Has specific methods to submit tasks to an ExecutorService


Implements a fluent API (CompletionStage) that allows chaining and
combining dependant tasks.


Allow to use different sized ExecutorServices for different tasks.
@DGOMEZG
Async with CompletableFuture
CompletableFuture.runAsync(getLongRunningTaskWithNoResult());
Async with CompletableFuture
CompletableFuture<Void> voidCF = 

CompletableFuture.runAsync(getLongRunningTaskWithNoResult());

doSomethingElse();
Async with CompletableFuture
CompletableFuture<Void> voidCF = 

CompletableFuture.runAsync(getLongRunningTaskWithNoResult());

doSomethingElse();

voidCF.get();
/
/
Wait until background task is finished
private static final Executor ASYNC_POOL = USE_COMMON_POOL ?

ForkJoinPool.commonPool() : new ThreadPerTaskExecutor();
Async with CompletableFuture
private static final Executor ASYNC_POOL = USE_COMMON_POOL ?

ForkJoinPool.commonPool() : new ThreadPerTaskExecutor();
Shared with the JVM (may affect parallel
streams)


Sized for CPU intensive tasks (if our task is
IO bound, we may affect app performance)


Daemon Threads (if our main thread
finishes, tasks may not be executed)
Same that


new Thread(task).start();
Async with CompletableFuture
CompletableFuture<Void> voidCF = 

CompletableFuture.runAsync(getLongRunningTaskWithNoResult());

doSomethingElse();

voidCF.get();
/
/
Wait until background task is finished
private static final Executor ASYNC_POOL = USE_COMMON_POOL ?

ForkJoinPool.commonPool() : new ThreadPerTaskExecutor();
Async with CompletableFuture
CompletableFuture<Void> voidCF = 

CompletableFuture.runAsync(getLongRunningTaskWithNoResult());

doSomethingElse();

voidCF.get();
/
/
Wait until background task is finished
ExecutorService executorService = Executors.newCachedThreadPool();

executorService
Async with CompletableFuture
CompletableFuture<Void> voidCF = 

CompletableFuture.runAsync(getLongRunningTaskWithNoResult()

, );

doSomethingElse();

voidCF.get();
/
/
Wait until background task is finished
ExecutorService executorService = Executors.newCachedThreadPool();

executorService
CompletableFuture<Void> voidCF = 

CompletableFuture.runAsync(getLongRunningTaskWithNoResult());

doSomethingElse();

voidCF.get();
/
/
Wait until background task is finished
Async with CompletableFuture
CompletableFuture<Void> voidCF = 

CompletableFuture.runAsync(getLongRunningTaskWithNoResult()

, );

doSomethingElse();

voidCF.get();
/
/
Wait until background task is finished
ExecutorService executorService = Executors.newCachedThreadPool();

executorService
Sized and used for the expected % of CPU used by
your tasks
Async with CompletableFuture
CompletableFuture<Void> voidCF = 

CompletableFuture.runAsync(getLongRunningTaskWithNoResult()

, );

doSomethingElse();

voidCF.get();
/
/
Wait until background task is finished
ExecutorService executorService = Executors.newCachedThreadPool();

executorService
CompletableFuture<Void> voidCF = 

CompletableFuture.runAsync(getLongRunningTaskWithNoResult()

, );

doSomethingElse();

voidCF.get();
/
/
Wait until background task is finished
NoResult()
Async with CompletableFuture
ExecutorService executorService = Executors.newCachedThreadPool();

executorService
CompletableFuture<Void> voidCF = 

CompletableFuture.runAsync(getLongRunningTaskWithNoResult()

, );

doSomethingElse();

voidCF.get();
/
/
Wait until background task is finished
NoResult()
Async with CompletableFuture
ExecutorService executorService = Executors.newCachedThreadPool();

executorService
Result()
CompletableFuture<Void> voidCF = 

CompletableFuture.runAsync(getLongRunningTaskWithNoResult()

, );

doSomethingElse();

voidCF.get();
/
/
Wait until background task is finished
Result()
Async with CompletableFuture
ExecutorService executorService = Executors.newCachedThreadPool();

executorService
CompletableFuture<Void> voidCF = 

CompletableFuture.runAsync(getLongRunningTaskWithNoResult()

, );

doSomethingElse();

voidCF.get();
/
/
Wait until background task is finished
sup Result()
Async with CompletableFuture
ExecutorService executorService = Executors.newCachedThreadPool();

executorService
Void> voidCF =
Async(getLongRunningTaskWithResult()
CompletableFuture<Void> voidCF = 

CompletableFuture.runAsync(getLongRunningTaskWithNoResult()

, );

doSomethingElse();

voidCF.get();
/
/
Wait until background task is finished
sup Async(getLongRunningTaskWithResult()
Async with CompletableFuture
ExecutorService executorService = Executors.newCachedThreadPool();

executorService
Void> voidCF =
ply
CompletableFuture<Void> voidCF = 

CompletableFuture.runAsync(getLongRunningTaskWithNoResult()

, );

doSomethingElse();

result.get();
/
/
Wait until background task is finished
String> result =
sup Async(getLongRunningTaskWithResult()
Async with CompletableFuture
ExecutorService executorService = Executors.newCachedThreadPool();

executorService
ply
CompletableFuture<T>
It may seem just an alternative to Future<T>
public class CompletableFuture<T> 

implements Future<T>, CompletionStage<T>
CompletionStage<T>
@DGOMEZG
CompletableFuture<T>
Fluent API to chain, compose and combine Futures.
CompletionStage<T>
acceptEither

applyToEither

runAfterEither

runAfterBoth

thenAccept

thenAcceptBoth

thenRun

thenCombine

thenCompose

whenAccept

@DGOMEZG
Finding exploitable concurrency
Find tasks that are independent and IO-Bound.


If some of them are inter-dependent, draw the flow of dependencies.
@DGOMEZG
An example
public void checkout(String cartId) {

ShoppingCart cart = shoppingCartService.findCartById(cartId);

List<ProductAvailability> availabilities = new ArrayList
<
>
();

for (CartItem cartItem : cart.getItems()) {

ProductAvailability productAvailability =

inventoryService.getProductAvailability(

cartItem.getProductId(), cartItem.getQuantity());

availabilities.add(productAvailability);

}

List<ScheduledDelivery> deliveries = groupDeliveriesByDate(availabilities);

BigDecimal deliveryQuote = getDeliveryQuoteFromCourierCompany();

BigDecimal price = calculateShippingCosts(deliveries, deliveryQuote);

}
An example
Example - Finding concurrency
Example - Finding concurrency
public void checkout(String cartId) {

CompletableFuture.supplyAsync(

()
-
>
shoppingCartService.findCartById(cartId)

).thenAcceptAsync(cart
-
>


cart.getItems()

.stream()

.map(item
-
>


CompletableFuture.supplyAsync(

()
-
>


inventoryService.getAvailability(

item.getProductId(), item.getQuantity())

).thenAcceptAsync(availability
-
>
groupDelivery(availability))

)

.collect(Collectors.toList())

.forEach(CompletableFuture
:
:
join);

}
CompletableFuture


In your API
Why should you consider using CompletableFuture
in you API?
Enable your users to maximise the performance to your queries.


And keep control on how you execute the asynchronous tasks
@DGOMEZG
Creating and managing CompletableFutures
CompletableFuture<String> completableFuture = new
CompletableFuture
<
>
();
@DGOMEZG
Creating and managing CompletableFutures
@DGOMEZG
Creating and managing CompletableFutures
@DGOMEZG
@DGOMEZG
An Example: QueryBus at AxonFramework
Queries
UI / API
Commands
Command Model
Projections
Events
An Example: QueryBus at AxonFramework
UI / API
Projections
queryMessage
@DGOMEZG
QueryBus
QueryBusImpl (simplified)
public CompletableFuture<QueryResponseMessage> query(QueryMessage query) {

/
/
Create your CompletableFuture

/
/
Prepare to Run asynchronously

/
/
get Results/Exceptions to complete the future

/
/
return your completableFuture

}
QueryBusImpl (simplified)
public CompletableFuture<QueryResponseMessage> query(QueryMessage query) {

/
/
Create your CompletableFuture

CompletableFuture<QueryResponseMessage> queryTransaction = 

new CompletableFuture
<
>
();

/
/
Prepare to Run asynchronously

/
/
get Results/Exceptions to complete the future

/
/
return your completableFuture

return queryTransaction;

}
QueryBusImpl (simplified)
public CompletableFuture<QueryResponseMessage> query(QueryMessage query) {

CompletableFuture<QueryResponseMessage> queryTransaction = 

new CompletableFuture
<
>
();

try {

/
/
Prepare to Run asynchronously

/
/
get Results to complete the future

} catch (Exception e) {

queryTransaction.completeExceptionally(exception);

}

return queryTransaction;

}
QueryBusImpl (simplified)
public CompletableFuture<QueryResponseMessage> query(QueryMessage query) {

CompletableFuture<QueryResponseMessage> queryTransaction = 

new CompletableFuture
<
>
();

try {

ResultStream<QueryResponse> result =

axonServerConnectionManager.getConnection(targetContext)

.query(query);

result.onAvailable(()
-
>


queryTransaction.complete(result.nextIfAvailable())

} catch (Exception e) {

queryTransaction.completeExceptionally(exception);

}

return queryTransaction;

}
With great power…
Some things to watch out
Using CompletableFuture in your API does not make it Async (we have a
SimpleQueryBusImpl which works in serial mode)


Beware of what ExecutorService you are using


(You don’t want to use common ForkJoin Pool or ThreadPerT
askExecutor)


CompletableFutures are powerful for composing and combining, but
sometimes is hard to get it right.
@DGOMEZG
Conclusions
Conclusions
CompletableFutures are a powerful tool to compose and combine
Asynchronous execution of heterogeneous tasks


Best if used with specific ExecutorService instances, properly sized based
depending on amount of I/O-Wait time


Adding CompletableFutures on you Async API will give more powers to the
developers using your library/framework.
@DGOMEZG
Where do I go from here?
Functional-Style Callbacks Using
Java 8’s CompletableFuture
https://www.infoq.com/articles/Functional-Style-Callbacks-Using-CompletableFuture/
Java
Newsletter
Advanced Java
Concurrency Courses
https://github.com/AxonFramework/AxonFramework
Quick Start Tutorial.


https://docs.axoniq.io/reference-guide/getting-started/quick-start
Free Courses on DDD, CQRS, Event-Sourcing


https://academy.axoniq.io/
lp.axoniq.io/jdd

More Related Content

What's hot (19)

PDF
What is new in java 8 concurrency
kshanth2101
 
PDF
DRYing to Monad in Java8
Dhaval Dalal
 
PDF
JavaOne 2013: Java 8 - The Good Parts
Konrad Malawski
 
PDF
If You Think You Can Stay Away from Functional Programming, You Are Wrong
Mario Fusco
 
PDF
Java 8 Stream API. A different way to process collections.
David Gómez García
 
PPTX
Typescript barcelona
Christoffer Noring
 
PDF
Java 8 Workshop
Mario Fusco
 
ODP
Finagle and Java Service Framework at Pinterest
Pavan Chitumalla
 
PPTX
разработка серверов и серверных приложений лекция №4
Eugeniy Tyumentcev
 
PPTX
Reactive programming with RxAndroid
Savvycom Savvycom
 
DOC
Ad java prac sol set
Iram Ramrajkar
 
PDF
Refactoring to Java 8 (Devoxx BE)
Trisha Gee
 
PPTX
Introduction to nsubstitute
Suresh Loganatha
 
KEY
Gwt and Xtend
Sven Efftinge
 
PDF
Concurrency Concepts in Java
Doug Hawkins
 
PDF
50 new things we can do with Java 8
José Paumard
 
PDF
Higher Order Components and Render Props
Nitish Phanse
 
PDF
Advanced Debugging Using Java Bytecodes
Ganesh Samarthyam
 
PDF
DI Frameworks - hidden pearls
Sven Ruppert
 
What is new in java 8 concurrency
kshanth2101
 
DRYing to Monad in Java8
Dhaval Dalal
 
JavaOne 2013: Java 8 - The Good Parts
Konrad Malawski
 
If You Think You Can Stay Away from Functional Programming, You Are Wrong
Mario Fusco
 
Java 8 Stream API. A different way to process collections.
David Gómez García
 
Typescript barcelona
Christoffer Noring
 
Java 8 Workshop
Mario Fusco
 
Finagle and Java Service Framework at Pinterest
Pavan Chitumalla
 
разработка серверов и серверных приложений лекция №4
Eugeniy Tyumentcev
 
Reactive programming with RxAndroid
Savvycom Savvycom
 
Ad java prac sol set
Iram Ramrajkar
 
Refactoring to Java 8 (Devoxx BE)
Trisha Gee
 
Introduction to nsubstitute
Suresh Loganatha
 
Gwt and Xtend
Sven Efftinge
 
Concurrency Concepts in Java
Doug Hawkins
 
50 new things we can do with Java 8
José Paumard
 
Higher Order Components and Render Props
Nitish Phanse
 
Advanced Debugging Using Java Bytecodes
Ganesh Samarthyam
 
DI Frameworks - hidden pearls
Sven Ruppert
 

Similar to Leveraging Completable Futures to handle your query results Asynchrhonously (20)

PDF
Leverage CompletableFutures to handle async queries. DevNexus 2022
David Gómez García
 
PPTX
Windows Phone 8 - 3.5 Async Programming
Oliver Scheer
 
PDF
Asynchronous Programming. Talk from ESUG2024
ESUG
 
ODP
Scala Future & Promises
Knoldus Inc.
 
PDF
Java concurrency model - The Future Task
Somenath Mukhopadhyay
 
PDF
Deep Dive async/await in Unity with UniTask(EN)
Yoshifumi Kawai
 
PPT
JSON Part 3: Asynchronous Ajax & JQuery Deferred
Jeff Fox
 
PDF
Promises look into the async future
slicejs
 
ODP
CompletableFuture
koji lin
 
DOCX
Parallel Programming With Dot Net
Neeraj Kaushik
 
PPTX
State in stateless serverless functions - Alex Pshul
CodeValue
 
PPTX
State in stateless serverless functions
Alex Pshul
 
PDF
Asynchronous development in JavaScript
Amitai Barnea
 
PDF
Effective JavaFX architecture with FxObjects
Srikanth Shenoy
 
PPT
Node.js: CAMTA Presentation
Rob Tweed
 
PPTX
Workshop: Async and Parallel in C#
Rainer Stropek
 
PPTX
Ddd melbourne 2011 C# async ctp
Pratik Khasnabis
 
PDF
Asynchronous API in Java8, how to use CompletableFuture
José Paumard
 
PPTX
NDC Sydney 2019 - Async Demystified -- Karel Zikmund
Karel Zikmund
 
Leverage CompletableFutures to handle async queries. DevNexus 2022
David Gómez García
 
Windows Phone 8 - 3.5 Async Programming
Oliver Scheer
 
Asynchronous Programming. Talk from ESUG2024
ESUG
 
Scala Future & Promises
Knoldus Inc.
 
Java concurrency model - The Future Task
Somenath Mukhopadhyay
 
Deep Dive async/await in Unity with UniTask(EN)
Yoshifumi Kawai
 
JSON Part 3: Asynchronous Ajax & JQuery Deferred
Jeff Fox
 
Promises look into the async future
slicejs
 
CompletableFuture
koji lin
 
Parallel Programming With Dot Net
Neeraj Kaushik
 
State in stateless serverless functions - Alex Pshul
CodeValue
 
State in stateless serverless functions
Alex Pshul
 
Asynchronous development in JavaScript
Amitai Barnea
 
Effective JavaFX architecture with FxObjects
Srikanth Shenoy
 
Node.js: CAMTA Presentation
Rob Tweed
 
Workshop: Async and Parallel in C#
Rainer Stropek
 
Ddd melbourne 2011 C# async ctp
Pratik Khasnabis
 
Asynchronous API in Java8, how to use CompletableFuture
José Paumard
 
NDC Sydney 2019 - Async Demystified -- Karel Zikmund
Karel Zikmund
 
Ad

More from David Gómez García (20)

PDF
Building Modular monliths that could scale to microservices (only if they nee...
David Gómez García
 
PDF
Building modular monoliths that could scale to microservices (only if they ne...
David Gómez García
 
PDF
Builiding Modular monoliths that can scale to microservices. JBCNConf 2021
David Gómez García
 
PDF
Cdm mil-18 - hypermedia ap is for headless platforms and data integration
David Gómez García
 
PDF
What's in a community like Liferay's
David Gómez García
 
PDF
T3chFest2016 - Uso del API JavaScript de Photoshop para obtener fotos HDTR
David Gómez García
 
PDF
Managing user's data with Spring Session
David Gómez García
 
PDF
Parallel streams in java 8
David Gómez García
 
PDF
Construccion de proyectos con gradle
David Gómez García
 
PDF
Midiendo la calidad de código en WTF/Min (Revisado EUI Abril 2014)
David Gómez García
 
PDF
Measuring Code Quality in WTF/min.
David Gómez García
 
PDF
Spring4 whats up doc?
David Gómez García
 
PDF
Gradle como alternativa a maven
David Gómez García
 
PDF
El poder del creador de Software. Entre la ingeniería y la artesanía
David Gómez García
 
PDF
Geo-SentimentZ
David Gómez García
 
PDF
HDTR images with Photoshop Javascript Scripting
David Gómez García
 
PDF
Wtf per lineofcode
David Gómez García
 
PDF
A real systemwithjms-rest-protobuf-mongodb
David Gómez García
 
PDF
Spring Data y Mongo DB en un proyecto Real
David Gómez García
 
PDF
NoSql y MongoDB
David Gómez García
 
Building Modular monliths that could scale to microservices (only if they nee...
David Gómez García
 
Building modular monoliths that could scale to microservices (only if they ne...
David Gómez García
 
Builiding Modular monoliths that can scale to microservices. JBCNConf 2021
David Gómez García
 
Cdm mil-18 - hypermedia ap is for headless platforms and data integration
David Gómez García
 
What's in a community like Liferay's
David Gómez García
 
T3chFest2016 - Uso del API JavaScript de Photoshop para obtener fotos HDTR
David Gómez García
 
Managing user's data with Spring Session
David Gómez García
 
Parallel streams in java 8
David Gómez García
 
Construccion de proyectos con gradle
David Gómez García
 
Midiendo la calidad de código en WTF/Min (Revisado EUI Abril 2014)
David Gómez García
 
Measuring Code Quality in WTF/min.
David Gómez García
 
Spring4 whats up doc?
David Gómez García
 
Gradle como alternativa a maven
David Gómez García
 
El poder del creador de Software. Entre la ingeniería y la artesanía
David Gómez García
 
Geo-SentimentZ
David Gómez García
 
HDTR images with Photoshop Javascript Scripting
David Gómez García
 
Wtf per lineofcode
David Gómez García
 
A real systemwithjms-rest-protobuf-mongodb
David Gómez García
 
Spring Data y Mongo DB en un proyecto Real
David Gómez García
 
NoSql y MongoDB
David Gómez García
 
Ad

Recently uploaded (20)

PDF
Fl Studio 24.2.2 Build 4597 Crack for Windows Free Download 2025
faizk77g
 
PDF
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
Fwdays
 
PDF
Complete JavaScript Notes: From Basics to Advanced Concepts.pdf
haydendavispro
 
PDF
Achieving Consistent and Reliable AI Code Generation - Medusa AI
medusaaico
 
PDF
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
PDF
"AI Transformation: Directions and Challenges", Pavlo Shaternik
Fwdays
 
PDF
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
PPTX
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
PDF
HCIP-Data Center Facility Deployment V2.0 Training Material (Without Remarks ...
mcastillo49
 
PDF
Empower Inclusion Through Accessible Java Applications
Ana-Maria Mihalceanu
 
PDF
LLMs.txt: Easily Control How AI Crawls Your Site
Keploy
 
PPTX
AUTOMATION AND ROBOTICS IN PHARMA INDUSTRY.pptx
sameeraaabegumm
 
PPTX
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
PDF
HubSpot Main Hub: A Unified Growth Platform
Jaswinder Singh
 
PDF
Blockchain Transactions Explained For Everyone
CIFDAQ
 
PDF
CIFDAQ Weekly Market Wrap for 11th July 2025
CIFDAQ
 
PDF
SWEBOK Guide and Software Services Engineering Education
Hironori Washizaki
 
PDF
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
PDF
Log-Based Anomaly Detection: Enhancing System Reliability with Machine Learning
Mohammed BEKKOUCHE
 
PDF
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
Fl Studio 24.2.2 Build 4597 Crack for Windows Free Download 2025
faizk77g
 
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
Fwdays
 
Complete JavaScript Notes: From Basics to Advanced Concepts.pdf
haydendavispro
 
Achieving Consistent and Reliable AI Code Generation - Medusa AI
medusaaico
 
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
"AI Transformation: Directions and Challenges", Pavlo Shaternik
Fwdays
 
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
HCIP-Data Center Facility Deployment V2.0 Training Material (Without Remarks ...
mcastillo49
 
Empower Inclusion Through Accessible Java Applications
Ana-Maria Mihalceanu
 
LLMs.txt: Easily Control How AI Crawls Your Site
Keploy
 
AUTOMATION AND ROBOTICS IN PHARMA INDUSTRY.pptx
sameeraaabegumm
 
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
HubSpot Main Hub: A Unified Growth Platform
Jaswinder Singh
 
Blockchain Transactions Explained For Everyone
CIFDAQ
 
CIFDAQ Weekly Market Wrap for 11th July 2025
CIFDAQ
 
SWEBOK Guide and Software Services Engineering Education
Hironori Washizaki
 
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
Log-Based Anomaly Detection: Enhancing System Reliability with Machine Learning
Mohammed BEKKOUCHE
 
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 

Leveraging Completable Futures to handle your query results Asynchrhonously

  • 1. Leveraging CompletableFutures to handle your query results asynchronously David Gómez G. Developer Advocate
  • 3. Concurrency Different type of tasks Usually do some works while waiting for other tasks to be completed. Have the work finished before Same type of tasks Workload split between similar workers Have the work finished before Parallelism @DGOMEZG
  • 5. Lots of tools since Java 1 Java has building blocks for Concurrency and parallelism since Java 1. Even when most desktop computers were single-core @DGOMEZG
  • 6. Threads Very Expensive Thread t = new Thread(task); t.start(); t.join(); Easily forgotten Blocking call
  • 12. Since Java 5 Concurrency & parallelism support improved in Java 5 Lots of New Concurrency constructors New concurrent-friendly Data Structures Revisited and improved in Java 7, 8, 9 … More coming up as part of loom project @DGOMEZG
  • 14. ExecutorService And now we can submit tasks that return a result. Executor Service, returns a Future<T> @DGOMEZG
  • 15. ExecutorService & Future<T> ExecutorService executorService = Executors.newCachedThreadPool(); Future<String> taskResult = executorService.submit(longRunningTaskWithResult); String s = taskResult.get(); Blocking call
  • 16. ExecutorService & Future<T> ExecutorService executorService = Executors.newCachedThreadPool(); Future<String> taskResult = executorService.submit(longRunningTaskWithResult); while (!taskResult.isDone()) { doSomethingElse(); } String s = taskResult.get(); False while task is not cancelled nor fi nished Improving performance by doing other tasks.
  • 17. Running Multiple T asks List<Future<String > > taskResults = new ArrayList < > (); for (Callable<String> task : tasks) { taskResults.add(executorService.submit(task)); } for (Future<String> result : taskResults) { processResult(result.get()); } Bene fi t only between submitting all tasks and getting the results
  • 18. Running Heterogeneous T asks List<Future<String > > taskResults = new ArrayList < > (); for (Callable<String> task : tasks) { taskResults.add(executorService.submit(task)); } for (Future<String> result : taskResults) { processResult(result.get()); } What if task1 is too slow while task2 is fast? What if we need the result of task1 to submit task2? (CompletionService returns tasks in the order they are fi nished)
  • 20. CompletableFuture<T> Introduced in Java8 Has specific methods to submit tasks to an ExecutorService Implements a fluent API (CompletionStage) that allows chaining and combining dependant tasks. Allow to use different sized ExecutorServices for different tasks. @DGOMEZG
  • 22. Async with CompletableFuture CompletableFuture<Void> voidCF = CompletableFuture.runAsync(getLongRunningTaskWithNoResult()); doSomethingElse();
  • 23. Async with CompletableFuture CompletableFuture<Void> voidCF = CompletableFuture.runAsync(getLongRunningTaskWithNoResult()); doSomethingElse(); voidCF.get(); / / Wait until background task is finished private static final Executor ASYNC_POOL = USE_COMMON_POOL ? ForkJoinPool.commonPool() : new ThreadPerTaskExecutor();
  • 24. Async with CompletableFuture private static final Executor ASYNC_POOL = USE_COMMON_POOL ? ForkJoinPool.commonPool() : new ThreadPerTaskExecutor(); Shared with the JVM (may affect parallel streams) Sized for CPU intensive tasks (if our task is IO bound, we may affect app performance) Daemon Threads (if our main thread finishes, tasks may not be executed) Same that new Thread(task).start();
  • 25. Async with CompletableFuture CompletableFuture<Void> voidCF = CompletableFuture.runAsync(getLongRunningTaskWithNoResult()); doSomethingElse(); voidCF.get(); / / Wait until background task is finished private static final Executor ASYNC_POOL = USE_COMMON_POOL ? ForkJoinPool.commonPool() : new ThreadPerTaskExecutor();
  • 26. Async with CompletableFuture CompletableFuture<Void> voidCF = CompletableFuture.runAsync(getLongRunningTaskWithNoResult()); doSomethingElse(); voidCF.get(); / / Wait until background task is finished ExecutorService executorService = Executors.newCachedThreadPool(); executorService
  • 27. Async with CompletableFuture CompletableFuture<Void> voidCF = CompletableFuture.runAsync(getLongRunningTaskWithNoResult() , ); doSomethingElse(); voidCF.get(); / / Wait until background task is finished ExecutorService executorService = Executors.newCachedThreadPool(); executorService CompletableFuture<Void> voidCF = CompletableFuture.runAsync(getLongRunningTaskWithNoResult()); doSomethingElse(); voidCF.get(); / / Wait until background task is finished
  • 28. Async with CompletableFuture CompletableFuture<Void> voidCF = CompletableFuture.runAsync(getLongRunningTaskWithNoResult() , ); doSomethingElse(); voidCF.get(); / / Wait until background task is finished ExecutorService executorService = Executors.newCachedThreadPool(); executorService Sized and used for the expected % of CPU used by your tasks
  • 29. Async with CompletableFuture CompletableFuture<Void> voidCF = CompletableFuture.runAsync(getLongRunningTaskWithNoResult() , ); doSomethingElse(); voidCF.get(); / / Wait until background task is finished ExecutorService executorService = Executors.newCachedThreadPool(); executorService
  • 30. CompletableFuture<Void> voidCF = CompletableFuture.runAsync(getLongRunningTaskWithNoResult() , ); doSomethingElse(); voidCF.get(); / / Wait until background task is finished NoResult() Async with CompletableFuture ExecutorService executorService = Executors.newCachedThreadPool(); executorService
  • 31. CompletableFuture<Void> voidCF = CompletableFuture.runAsync(getLongRunningTaskWithNoResult() , ); doSomethingElse(); voidCF.get(); / / Wait until background task is finished NoResult() Async with CompletableFuture ExecutorService executorService = Executors.newCachedThreadPool(); executorService Result()
  • 32. CompletableFuture<Void> voidCF = CompletableFuture.runAsync(getLongRunningTaskWithNoResult() , ); doSomethingElse(); voidCF.get(); / / Wait until background task is finished Result() Async with CompletableFuture ExecutorService executorService = Executors.newCachedThreadPool(); executorService
  • 33. CompletableFuture<Void> voidCF = CompletableFuture.runAsync(getLongRunningTaskWithNoResult() , ); doSomethingElse(); voidCF.get(); / / Wait until background task is finished sup Result() Async with CompletableFuture ExecutorService executorService = Executors.newCachedThreadPool(); executorService Void> voidCF = Async(getLongRunningTaskWithResult()
  • 34. CompletableFuture<Void> voidCF = CompletableFuture.runAsync(getLongRunningTaskWithNoResult() , ); doSomethingElse(); voidCF.get(); / / Wait until background task is finished sup Async(getLongRunningTaskWithResult() Async with CompletableFuture ExecutorService executorService = Executors.newCachedThreadPool(); executorService Void> voidCF = ply
  • 35. CompletableFuture<Void> voidCF = CompletableFuture.runAsync(getLongRunningTaskWithNoResult() , ); doSomethingElse(); result.get(); / / Wait until background task is finished String> result = sup Async(getLongRunningTaskWithResult() Async with CompletableFuture ExecutorService executorService = Executors.newCachedThreadPool(); executorService ply
  • 36. CompletableFuture<T> It may seem just an alternative to Future<T> public class CompletableFuture<T> implements Future<T>, CompletionStage<T> CompletionStage<T> @DGOMEZG
  • 37. CompletableFuture<T> Fluent API to chain, compose and combine Futures. CompletionStage<T> acceptEither applyToEither runAfterEither runAfterBoth thenAccept thenAcceptBoth thenRun thenCombine thenCompose whenAccept @DGOMEZG
  • 38. Finding exploitable concurrency Find tasks that are independent and IO-Bound. If some of them are inter-dependent, draw the flow of dependencies. @DGOMEZG
  • 39. An example public void checkout(String cartId) { ShoppingCart cart = shoppingCartService.findCartById(cartId); List<ProductAvailability> availabilities = new ArrayList < > (); for (CartItem cartItem : cart.getItems()) { ProductAvailability productAvailability = inventoryService.getProductAvailability( cartItem.getProductId(), cartItem.getQuantity()); availabilities.add(productAvailability); } List<ScheduledDelivery> deliveries = groupDeliveriesByDate(availabilities); BigDecimal deliveryQuote = getDeliveryQuoteFromCourierCompany(); BigDecimal price = calculateShippingCosts(deliveries, deliveryQuote); }
  • 41. Example - Finding concurrency
  • 42. Example - Finding concurrency
  • 43. public void checkout(String cartId) { CompletableFuture.supplyAsync( () - > shoppingCartService.findCartById(cartId) ).thenAcceptAsync(cart - > cart.getItems() .stream() .map(item - > CompletableFuture.supplyAsync( () - > inventoryService.getAvailability( item.getProductId(), item.getQuantity()) ).thenAcceptAsync(availability - > groupDelivery(availability)) ) .collect(Collectors.toList()) .forEach(CompletableFuture : : join); }
  • 45. Why should you consider using CompletableFuture in you API? Enable your users to maximise the performance to your queries. And keep control on how you execute the asynchronous tasks @DGOMEZG
  • 46. Creating and managing CompletableFutures CompletableFuture<String> completableFuture = new CompletableFuture < > (); @DGOMEZG
  • 47. Creating and managing CompletableFutures @DGOMEZG
  • 48. Creating and managing CompletableFutures @DGOMEZG
  • 49. @DGOMEZG An Example: QueryBus at AxonFramework Queries UI / API Commands Command Model Projections Events
  • 50. An Example: QueryBus at AxonFramework UI / API Projections queryMessage @DGOMEZG QueryBus
  • 51. QueryBusImpl (simplified) public CompletableFuture<QueryResponseMessage> query(QueryMessage query) { / / Create your CompletableFuture / / Prepare to Run asynchronously / / get Results/Exceptions to complete the future / / return your completableFuture }
  • 52. QueryBusImpl (simplified) public CompletableFuture<QueryResponseMessage> query(QueryMessage query) { / / Create your CompletableFuture CompletableFuture<QueryResponseMessage> queryTransaction = new CompletableFuture < > (); / / Prepare to Run asynchronously / / get Results/Exceptions to complete the future / / return your completableFuture return queryTransaction; }
  • 53. QueryBusImpl (simplified) public CompletableFuture<QueryResponseMessage> query(QueryMessage query) { CompletableFuture<QueryResponseMessage> queryTransaction = new CompletableFuture < > (); try { / / Prepare to Run asynchronously / / get Results to complete the future } catch (Exception e) { queryTransaction.completeExceptionally(exception); } return queryTransaction; }
  • 54. QueryBusImpl (simplified) public CompletableFuture<QueryResponseMessage> query(QueryMessage query) { CompletableFuture<QueryResponseMessage> queryTransaction = new CompletableFuture < > (); try { ResultStream<QueryResponse> result = axonServerConnectionManager.getConnection(targetContext) .query(query); result.onAvailable(() - > queryTransaction.complete(result.nextIfAvailable()) } catch (Exception e) { queryTransaction.completeExceptionally(exception); } return queryTransaction; }
  • 56. Some things to watch out Using CompletableFuture in your API does not make it Async (we have a SimpleQueryBusImpl which works in serial mode) Beware of what ExecutorService you are using (You don’t want to use common ForkJoin Pool or ThreadPerT askExecutor) CompletableFutures are powerful for composing and combining, but sometimes is hard to get it right. @DGOMEZG
  • 58. Conclusions CompletableFutures are a powerful tool to compose and combine Asynchronous execution of heterogeneous tasks Best if used with specific ExecutorService instances, properly sized based depending on amount of I/O-Wait time Adding CompletableFutures on you Async API will give more powers to the developers using your library/framework. @DGOMEZG
  • 59. Where do I go from here? Functional-Style Callbacks Using Java 8’s CompletableFuture https://www.infoq.com/articles/Functional-Style-Callbacks-Using-CompletableFuture/ Java Newsletter Advanced Java Concurrency Courses https://github.com/AxonFramework/AxonFramework Quick Start Tutorial. 
 https://docs.axoniq.io/reference-guide/getting-started/quick-start Free Courses on DDD, CQRS, Event-Sourcing 
 https://academy.axoniq.io/ lp.axoniq.io/jdd