e.g. I looking to find a way to execute @Async
method not absolutely asynchronously.
For example I want to invoke @Async
task that will block my process for a up to a maximum defined time if task still haven't completed.
@Async
public Future<ModelObject> doSomething() {
//here we will block for a max allowed time if task still haven't been completed
}
So such code will be semi asynchronous but the blocking time can be controlled by developer.
P.S : of course I can achieve this by simply blocking calling thread for a limited time. but I look to achieve that within spring layer
In short, no, there is no way to configure Spring to do this.
The @Async
annotation is handled by the AsyncExecutionInterceptor
which delegates the work to a AsyncTaskExecutor
. You could, in theory, write your own implementation of the AsyncTaskExecutor
but even then there would be no way to use the @Async
annotation to pass the desired wait time to your executor. Even then, it's not clear to me what the caller's interface would look like since they'd still be getting a Future
object back. You would probably also need to subclass the Future
object as well. Basically, by the time you are finished, you will have written the entire feature again more or less from scratch.
You could always wrap the returned Future
object in your own WaitingFuture
proxy which provides an alternate get implementation although even then you'd have no way of specifying the wait value on the callee side:
WaitingFuture<ModelObject> future = new WaitingFuture<ModelObject>(service.doSomething());
ModelObject result = future.get(3000); //Instead of throwing a timeout, this impl could just return null if 3 seconds pass with no answer
if(result == null) {
//Path A
} else {
//Path B
}
Or if you don't want to write your own class then just catch the TimeoutException
.
Future<ModelObject> future = doSomething();
try {
ModelObject result = future.get(3000,TimeUnit.MILLISECONDS);
//Path B
} catch (TimeoutException ex) {
//Path A
}