2012-06-06 22 views
6

Mi aplicación Java requiere una lógica de reintento en las llamadas remotas. Estas llamadas remotas son:Reintentar llamadas al método de manera genérica

  • dispersos por todo la aplicación
  • pertenecen a diferentes clases de servicio remoto.

Además, la lógica de reintento puede tener un intervalo de reintento variable e intentos de reintento variables.

Necesito una implementación genérica de retry() que pueda realizar llamadas al método apropiado según el lugar al que se llame. A continuación se muestra una ilustración de código simple de lo que estoy buscando. Sé que podemos intentar hacer esto usando la reflexión de Java, pero, ¿hay un marco o una fuente abierta disponible en algún lugar que sea de lectura y uso?

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 
} 

Respuesta

0

¿dónde obtienes los servicios? use una fábrica para Proxy el servicio que obtiene de la fábrica original. El proxy puede implementar el reintento de forma transparente. Ver los Proxy/ProxyGenerators de Java en reflexión.

0

Supongamos que tiene un método que necesita volverse a unir cada 500 ms y hasta 5 veces. clase actual:

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

enfoque de modificación:

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; 
     } 
    } 
} 
Cuestiones relacionadas