Asynchronous BulkHeads with Fallback and MicroProfile 📎
The org.eclipse.microprofile.faulttolerance.Asynchronous
annotation together with
org.eclipse.microprofile.faulttolerance.Bulkhead
introduces a configurable and monitorable
thread pool "on-the-fly":
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.function.Consumer;
import org.eclipse.microprofile.faulttolerance.Asynchronous;
import org.eclipse.microprofile.faulttolerance.Bulkhead;
import org.eclipse.microprofile.faulttolerance.Fallback;
import org.eclipse.microprofile.metrics.annotation.Counted;
public class AsynchronousCalculator {
@Counted
@Asynchronous
@Fallback(fallbackMethod = "onOverload")
@Bulkhead(value = 2, waitingTaskQueue = 10)
public Future intenseCalculation(Consumer resultListener) {
int computation = 2 * 21;
resultListener.accept(computation);
return CompletableFuture.completedFuture(null);
}
/**
* onOverload is called on overload :-)
*/
public Future onOverload(Consumer resultListener) {
System.out.println("Please call me next time later");
resultListener.accept(13);
return CompletableFuture.completedFuture(null);
}
}
The fully optional org.eclipse.microprofile.metrics.annotation.Counted
annotation causes the application server
to emit the metric: "application:com_airhacks_asynchronous_control_asynchronous_calculator_intense_calculation 15"
which reflects the current number of instances and so the number of parallel processes (in this example 15) at the same time.
On top of that also Bulkhead metrics and fallback counters are emitted (excerpt):
# TYPE (...)_calculator_intense_calculation_fallback_calls_total counter
(...)_calculator_intense_calculation_fallback_calls_total 0
# TYPE (...)_calculator_intense_calculation_bulkhead_execution_duration_mean_seconds gauge
(...)_calculator_intense_calculation_bulkhead_execution_duration_mean_seconds 1.00234796556958
# TYPE (...)_calculator_intense_calculation_bulkhead_execution_duration_max_seconds gauge
(...)_calculator_intense_calculation_bulkhead_execution_duration_max_seconds 1.007435808
# TYPE (...)_calculator_intense_calculation_bulkhead_execution_duration_min_seconds gauge
(...)_calculator_intense_calculation_bulkhead_execution_duration_min_seconds 1.0000803550000001
# TYPE (...)_calculator_intense_calculation_bulkhead_execution_duration_stddev_seconds gauge
(...)_calculator_intense_calculation_bulkhead_execution_duration_stddev_seconds 0.0016244590722208272
# TYPE (...)_calculator_intense_calculation_bulkhead_execution_duration_seconds summary
(...)_calculator_intense_calculation_bulkhead_execution_duration_seconds_count 2370
(...)_calculator_intense_calculation_bulkhead_execution_duration_seconds{quantile="0.5"} 1.002190041
(...)_calculator_intense_calculation_bulkhead_execution_duration_seconds{quantile="0.75"} 1.003775723
(...)_calculator_intense_calculation_bulkhead_execution_duration_seconds{quantile="0.95"} 1.0051155980000002
(...)_calculator_intense_calculation_bulkhead_execution_duration_seconds{quantile="0.98"} 1.005298392
(...)_calculator_intense_calculation_bulkhead_execution_duration_seconds{quantile="0.99"} 1.005314287
(...)_calculator_intense_calculation_bulkhead_execution_duration_seconds{quantile="0.999"} 1.006405762
# TYPE (...)_calculator_intense_calculation_bulkhead_calls_accepted_total counter
(...)_calculator_intense_calculation_bulkhead_calls_accepted_total 2400
(...)
The @Asynchronous
methods can be easily combined with asynchronous JAX-RS resources:
@RequestScoped
@Produces(MediaType.TEXT_PLAIN)
@Path("calculations")
public class CalculationsResource {
@Inject
AsynchronousCalculator worker;
@GET
public void ping(@Suspended AsyncResponse response) {
worker.intenseCalculation(response::resume);
}
}
The size of the WAR is 6kB. Build time: 2986 ms, deploy time: 0.233 seconds. Built and deployed with WAD and tested with openliberty (the largest possible installation with all Java EE 8 + MicroProfile features enabled).
The general availability of MicroProfile on all major application servers makes the Porcupine superfluous and your WARs a few KB thinner.
See you at Web, MicroProfile and Java EE Workshops at Munich Airport, Terminal 2 or Virtual Dedicated Workshops / consulting. Is Munich's airport too far? Learn from home: airhacks.io.