2011-08-17 14 views

Respuesta

12

Se puede construir su propio método de ayuda en el maravilloso para encapsular esta lógica de reintento.

def retry(int times = 5, Closure errorHandler = {e-> log.warn(e.message,e)} 
    , Closure body) { 
    int retries = 0 
    def exceptions = [] 
    while(retries++ < times) { 
    try { 
     return body.call() 
    } catch(e) { 
     exceptions << e 
     errorHandler.call(e) 
    }   
    } 
    throw new MultipleFailureException("Failed after $times retries", exceptions) 
} 

(Asumiendo una definición de MultipleFailureException similar a GPars' AsyncException)

a continuación en el código, se puede utilizar este método de la siguiente manera.

retry { 
    errorProneOperation() 
} 

o, con un número diferente de reintentos y el comportamiento de la gestión de errores:

retry(2, {e-> e.printStackTrace()}) { 
    errorProneOperation() 
} 
+1

Ahora bien, si el 'IllegalStateException' usaría una de las excepciones (el primero el último disco que decir??) Como su causa sería ** mucho ** más útil, como se podía ver ** por qué ** falló. En producción, no me gustaría imprimir una pila cada vez que fallara un intento. Solo quiero saber si todos los intentos han fallado. –

+0

Gracias Joachim: a sugerencia de usted, agregué la recopilación de excepciones individuales. En cuanto a no querer una acumulación de pila, seguro, está ahí para ilustrar el punto. Como las excepciones ahora se recopilan para informar al final, tal vez el propósito del errorHandler es restablecer los recursos necesarios antes de que 'body.call()' se reintente, en cuyo caso el cierre predeterminado podría ser '{->} ' – winstaan74

+0

Terminé usando algo muy similar. gracias winstaan. –

1

En estos días, la gente le aconsejará que use ScheduledExecutorService para implementar este tipo de funcionalidad try-catch-retry, ya que Thread.sleep() se considera obsoleto y potencialmente perjudicial para el rendimiento. Iba a señalarte una buena respuesta sobre esto por cletus, pero no puedo por mi vida encontrarla. Actualizaré mi respuesta si puedo desenterrarla.

EDIT: lo encontró: How to retry function request after a certain time Espero que esto sea de alguna ayuda para usted.

1

puedo sugerir para emular un poco la misma (no estoy seguro acerca de la semántica de retry):

def retry(handler, c) { 
    try { 
     c() 
    } catch(e) { 
     handler(e) 
     retry(handler, c) // restart from beginning 
    } 
} 

def handler = {e -> 
    // handles error 
} 

retry(handler) { 
    do_something // exception raised 
} 
Cuestiones relacionadas