Description
So we have asynchronous fault tolerance strategies for CompletionStage
-returning methods, but those only apply if the method is also @Asynchronous
. If the method is not annotated @Asynchronous
, then all the fault tolerance strategies treat the method as synchronous and only apply around the method call.
If I have a truly asynchronous method, I don't want to add @Asynchronous
, because that leads to an explicit move to an extra thread. (There can be several reasons why I don't want that. For example, the method itself can already spawn an extra thread. Or the method can execute on an event loop. Etc.)
This is not a made-up scenario -- I found about this issue when trying to use MP RestClient with MP Fault Tolerance! In MP RestClient, if the method returns CompletionStage
, that itself means that the RestClient implementation needs to run the method asynchronously. Adding @Asynchronous
means that Fault Tolerance will also run it asynchronously. That's a waste of resources.
In other words, the @Asynchronous
annotation has a very narrow meaning -- basically, it always means offloading to an extra thread. That is very limiting. For example, in an event loop world, everything is asynchronous yet running on a single thread (or a small thread pool).
I believe we need to add an ability to let CompletionStage
-returning methods be treated as asynchronous without offloading to an extra thread. I can see several ways of achieving that:
- If a
CompletionStage
-returning method isn't annotated@Asynchronous
, we still apply all the fault tolerance strategies asynchronously. Here, the@Asynchronous
annotation basically retains the narrow meaning of "force offloading to an extra thread". - Variant of the above option: rename
@Asynchronous
to@ThreadOffload
, so that it's clear what the annotation does. We'd still treat the return type as the primary indicator of whether the method is asynchronous or not. - Modify the
@Asynchronous
annotation to be able to signalize whether offloading to an extra thread is desired. For example,@Asynchronous(threadOffload = true)
to offload to an extra thread, and@Asynchronous(threadOffload = false)
for staying on the original thread. Here, the@Asynchronous
annotation becomes more general. We'd probably defaultthreadOffload
totrue
to stay compatible, and trust user that they know they need to setthreadOffload = false
. - Perhaps more, can't think of anything right now.