General Recall Method Call

My Java application requires repeated logic when remote calls fail. These remote calls are:

  • scattered throughout the application
  • belong to different classes of Remote Service.

In addition, the retry logic may have a variable retry interval and various retry attempts.

I need a generic retry () implementation that can call the appropriate method calls depending on where it is being called from. Below is a simple illustration of the code I'm looking for. I know that we can try to do this using java reflection, but is there any open source environment or source somewhere that is readable?

try { ClassA objA = remoteServiceA.call(paramA1, paramA2, ...); } catch (Exception e){ ClassA objA = (ClassA)retry(remoteService, listOfParams, ..); // generic method call } .. try { ClassB objB = remoteServiceB.call(paramB1, paramB2, ...); } catch (Exception e){ ClassA objB = (ClassB)retry(remoteService, listOfParams, ..); // generic method call } 
+6
source share
4 answers

As already suggested, you should use AOP and Java annotations. I would recommend a reading mechanism from the jcabi aspects (I'm a developer):

 @RetryOnFailure(attempts = 3, delay = 5) public String load(URL url) { return url.openConnection().getContent(); } 

Read also this blog entry: http://www.yegor256.com/2014/08/15/retry-java-method-on-exception.html

Update: Select RetryFunc from Cactoos .

+7
source

This is an example book where (or in general) can use 8.2.7 Example in Spring documentation and 5 Reasons Java developers should learn and use AspectJ .

Basically, the aspect intercepts all calls for given methods (defined using annotations, naming conventions, whatever) and repetitions.

+1
source

where do you get services from? use factory for the proxy you get from the original factory. The proxy server can then retry transparently. See Java proxy / ProxyGenerators in reflection.

0
source

Suppose you have a method that needs to be loaded every 500 ms and up to 5 times. Current class :

 public class RemoteCaller{ Service serviceCaller; public void remoteCall(String message) { serviceCaller.updateDetails( this.message); return null; } } 

Modified Approach:

 public class RetriableHelper<T> implements Callable<T> { private Callable<T> task; private int numberOfRetries; private int numberOfTriesLeft; private long timeToWait; public RetriableHelper(int numberOfRetries, long timeToWait, Callable<T> task) { this.numberOfRetries = numberOfRetries; numberOfTriesLeft = numberOfRetries; this.timeToWait = timeToWait; this.task = task; } public T call() throws Exception { while (true) { try { return task.call(); } catch (InterruptedException e) { throw e; } catch (CancellationException e) { throw e; } catch (Exception e) { numberOfTriesLeft--; if (numberOfTriesLeft == 0) { throw e; } Thread.sleep(timeToWait); } } } } Backend system/remote call class: public class RemoteCaller{ Service serviceCaller; public void remoteCall(String message) { class RemoteCallable implements Callable<Void> { String message; public RemoteCallable( String message) { this.message = message; } public Void call() throws Exception{ serviceCaller.updateDetails( this.message); return null; } } RetriableHelper<Void> retriableHelper = new RetriableHelper<Void>(5, 500, new RemoteCallable( message)); try { retriableHelper.call(); } catch (Exception e) { throw e; } } } 
0
source

Source: https://habr.com/ru/post/917482/


All Articles