2010-10-14 6 views
7

Estoy haciendo una solicitud http. Estoy en una plataforma (Android) donde las operaciones de red a menudo fallan porque la conexión de red podría no estar disponible de inmediato. Por lo tanto, me gustaría probar la misma conexión N veces antes de fallar por completo. Estaba pensando en algo como esto:Reintentando una conexión HTTP

DefaultHttpClient mHttp = ...; 

public HttpResponse runHttpRequest(HttpRequestBase httpRequest) 
    throws IOException 
{ 
    IOException last = null; 
    for (int attempt = 0; attempt < 3; attempt++) { 
     try { 
      HttpResponse response = mHttpClient.execute(httpRequest); 
      int statusCode = response.getStatusLine().getStatusCode(); 
      if (statusCode == 200) { 
       return response; 
      } 
     } catch (IOException e) { 
      httpRequest.abort(); 
      last = e; 
     } 
    } 

    throw last; 
} 

Lo que más me preocupa es la conexión de algún estado que no es válido en reintentos subsiguientes. En otras palabras, ¿necesito recrear completamente 'httpRequest', debería evitar llamar a httpRequest.abort() en el bloque catch, y solo llamarlo en la falla final?

Gracias

Respuesta

7

La documentación no menciona que ocurrirá tal cosa, a pesar de que lo tienes que probarlo. Sin embargo, lo más importante es que hay algunas cosas que debe considerar con su código ...

  1. Probablemente debería exponer el número de reintentos, permitiendo que la persona que llama especifique este valor.
  2. Solo debe volver a intentar si se lanzó una excepción; lo intentas de nuevo a menos que obtengas un 200. Sin embargo, si, por ejemplo, obtienes un 404 ... esto no significa que tu solicitud falló en el sentido de que la red no falló ... más bien, hiciste una ronda exitosa- viaje al servidor, pero el servidor simplemente no tiene el recurso solicitado ... por lo que realmente no tiene sentido volver a intentarlo en tal caso.
  3. Tal como está, puede suprimir todo tipo de diferentes tipos de excepciones. Puede tener sentido registrar todas las excepciones que ocurrieron en una Lista y devolver algún tipo de objeto de resultado que contenga la respuesta (posiblemente nulo si todos los intentos fallaron) además de una lista de todas las excepciones. De lo contrario, arroja alguna excepción arbitraria del conjunto de excepciones que ocurrieron, posiblemente oscureciendo la falla.
  4. En este momento usted simplemente se queja con la misma solicitud, una y otra vez ... si hay congestión, solo está agregando a ella. Y si su dirección IP fue prohibida por demasiada actividad, es probable que vaya a agregar eso ... cualquier tipo de lógica de reintento debería tener un comportamiento de retroceso donde hay cierta cantidad de espera entre reintentos y ese intervalo aumenta con cada falla
3

lo recomiendo a utilizar AOP y Java anotaciones de jcabi-aspects (soy un desarrollador):

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