CDI bean creation is synchronous. As a result if you inject a bean whose initialization involves potentially blocking operations (e.g. fetch some data from DB) there creation process is blocked until the dependency is ready. AsyncReference is an asynchronously processed wrapper (actually also implements CompletionStage) of an injectable reference which allows to finish the client bean creation before the dependency is ready:
If there is a producer method whose return type is CompletionStage where the result type matches the required type (according to type-safe resolution rules) then produced CompletionStage#whenComplete(java.util.function.BiConsumer) is used to process the reference. Otherwise, a Vertx worker thread is used so that the processing does not block the event loop thread.
AsyncWorker
AsyncWorker allows to wrap a synchronous action as an asynchronous computation. The action is performed either as blocking operation using a Vertx worker thread or as non-blocking operation using the Vertx event-loop thread:
@Dependent
public class Hello {
@Inject
AsyncWorker worker;
@Inject
Service service;
CompletionStage<String> hello() {
return worker.performBlocking(service::getMessageFromDb).thenApply(m -> "Hello " + m + "!");
}
}
It's also possible to combine these two constructs:
public class HelloCombo {
@Inject
AsyncWorker worker;
@Inject
AsyncReference<Service> serviceRef;
CompletionStage<String> hello() {
return serviceRef.thenCompose(service ->
// At this point Service is ready
// But getMessage() is also blocking
worker.performBlocking(service::getMessage)
// Finally modify the final message
.thenApply(m -> "Hello " + m + "!"));
}
}
This PR introduces two new constructs:
AsyncReference
AsyncWorker
AsyncReference
CDI bean creation is synchronous. As a result if you inject a bean whose initialization involves potentially blocking operations (e.g. fetch some data from DB) there creation process is blocked until the dependency is ready.
AsyncReference
is an asynchronously processed wrapper (actually also implementsCompletionStage
) of an injectable reference which allows to finish the client bean creation before the dependency is ready:If there is a producer method whose return type is
CompletionStage
where the result type matches the required type (according to type-safe resolution rules) then producedCompletionStage#whenComplete(java.util.function.BiConsumer)
is used to process the reference. Otherwise, a Vertx worker thread is used so that the processing does not block the event loop thread.AsyncWorker
AsyncWorker
allows to wrap a synchronous action as an asynchronous computation. The action is performed either as blocking operation using a Vertx worker thread or as non-blocking operation using the Vertx event-loop thread:It's also possible to combine these two constructs: