2010-10-14 16 views
7

Sto facendo una richiesta http. Sono su una piattaforma (Android) in cui le operazioni di rete spesso falliscono perché la connessione di rete potrebbe non essere immediatamente disponibile. Quindi mi piacerebbe provare la stessa connessione N volte prima di fallire completamente. Stavo pensando a qualcosa di simile:Nuovo tentativo di connessione 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; 
} 

Sono per lo più preoccupati per il collegamento di essere in uno stato che non è valido su tentativi successivi. In altre parole, devo ricreare completamente "httpRequest", dovrei evitare di chiamare httpRequest.abort() nel blocco catch e chiamarlo solo nell'ultimo errore?

Grazie

risposta

7

La documentazione non parlare che si verifichi una cosa del genere, anche se dovreste provarlo. Ancora più importante, però, ci sono alcune cose che dovresti considerare con il tuo codice ...

  1. Probabilmente dovresti esporre il numero di tentativi, consentendo al chiamante di specificare questo valore.
  2. È necessario riprovare solo se è stata generata un'eccezione; stai provando al momento, a meno che tu non abbia un 200. Tuttavia se, ad esempio, ottieni un 404 ... questo non significa che la tua richiesta è fallita nel senso che la rete non ha fallito ... piuttosto, hai fatto un round di successo viaggio al server, ma il server semplicemente non ha la risorsa richiesta ... quindi non ha senso riprovare in questo caso.
  3. Così com'è, è possibile eliminare tutti i tipi di diversi tipi di eccezioni. Potrebbe avere senso registrare tutte le eccezioni che si sono verificate in un elenco e restituire una sorta di oggetto risultato che contiene la risposta (eventualmente null se tutti i tentativi falliscono) oltre a un elenco di tutte le eccezioni. Altrimenti, si genera un'eccezione arbitraria dall'insieme di eccezioni che si sono verificate, probabilmente oscurando l'errore.
  4. In questo momento, basta martellare via con la stessa richiesta, più e più volte ... se c'è congestione, ci stai semplicemente aggiungendo. E se il tuo indirizzo IP è stato bannato per troppa attività, probabilmente stai andando ad aggiungerlo ... qualsiasi tipo di logica di retry dovrebbe avere un comportamento di back-off dove c'è una certa quantità di attesa tra i tentativi e quell'intervallo aumenta con ogni fallimento.
3

mi consiglia di utilizzare AOP e Java annotazioni da jcabi-aspects (Sono uno sviluppatore):

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