2

I have a Spring method annotated with @Async

@Async
public void doSomething(long id, String text) {
    //do something
}

The method invokes a remote service, which occasionally times out. Is there a way to catch the timeout and resubmit the task to the @Async method N seconds later?

I doubt calling the annotated method from inside itself will work because Spring uses a pointcut to intercept invocations.

The only way I can think of is to override AsyncExecutionAspectSupport.handleError to rebuild an instanceof MethodInvocation and then call a copy of AsyncExecutionInterceptor.invoke that lets me specify a delay.

Is there another way? Perhaps someone has already done it?


An Aside

I can imagine a solution whereby @Async is extended to specify cases for retry, in much the same way that transactions are managed in Spring but this is more fundamental than the theoretical solution described above!

@Async(retryOn=TimeoutException.class, maxRetries=2, delayStrategy=DelayStrategy.DOUBLE)
Rich
  • 15,602
  • 15
  • 79
  • 126
  • 2
    Does this help? https://howtodoinjava.com/spring-boot2/spring-retry-module/ – M. Prokhorov Aug 06 '19 at 14:53
  • It might do, I wasn't aware of that project. I'll have to have a look at it. – Rich Aug 06 '19 at 15:02
  • I've had a look at the Spring Retry Module, and it doesn't seem to release the calling thread during the retry. I'm specifically looking for a solution that frees the thread during the backoff period. – Rich Aug 07 '19 at 13:55
  • Spring is pretty configurable, so it's quite possible that you can code this retry policy (or however it's named) yourself. – M. Prokhorov Aug 07 '19 at 16:50

0 Answers0