2017-03-21 1 views
0

Ich benutze sowohl Refit und Polly, um zu Restful APIs zu rufen und ich frage mich, was die Wiederholung (falls vorhanden) -Richtlinie für Refits ApiException sein sollte?Best Retry Policy für Refit ApiException?

public static PolicyWrap MyRetryPolicy() 
{ 
     // Try few times with little more time between... maybe the 
     // connection issue gets resolved 
     var wireServerNetworkIssue = Policy.Handle<WebException>() 
            .WaitAndRetryAsync(new[] { 
            TimeSpan.FromSeconds(1), 
            TimeSpan.FromSeconds(2), 
            TimeSpan.FromSeconds(4)}); 
     var policyList = new List<Policy>(); 

     // But if there is something wrong with the api 
     // I should do what (if general)? 
     var api = Policy.Handle<ApiException>() 
        .RetryAsync(1, onRetry: async (exception, i) => 
        { 
         await Task.Run(() => 
         { 
          // What would be normal to do here? 
          // Try again or do some circuit braking? 
         }); 
        }); 

     policyList.Add(wireServerNetworkIssue); 
     policyList.Add(api); 

     return Policy.Wrap(policyList.ToArray()); 
} 

Und dann benutze ich es wie diese

try 
{ 
    myApi = RestService.For<MyApi>("api base url"); 
    var policyWrapper = Policies.Policies.MyRetryPolicyWrapper(); 
    var response = await policy.ExecuteAsync(() => myApi.SendReceiptAsync(receipt)); 
} 
catch (ApiException apiEx) 
{ 
    //Do something if the retry policy did´t fix it. 
} 
catch (WebException webEx) 
{ 
    //Do something if the retry policy did´t fix it. 
} 

die Frage

Was eine normale Wiederholungs Politik für ApiExceptions wäre? Würden Sie nur die Bremse ziehen oder unter welchen Umständen würden Sie etwas tun, um sich zu erholen?

Die Antwort ist wahrscheinlich "es hängt davon ab, was Ihr Service zurückgibt", aber ich muss nur fragen.

+0

Sie sollten die 'appeaTask.Run (() => {});' im 'onRetry'-Delegaten Ihrer ursprünglichen Frage nicht benötigen (es sei denn, Sie möchten die' onRetry'-Aktion möglicherweise in einem Hintergrundthread ausführen). Die Verwendung von 'await' innerhalb des Delegates gibt dem Delegaten einen' Task'-basierten Rückgabetyp. Wenn Sie möchten, dass die onretry-Aktion asynchron ausgeführt wird, verwenden Sie außerdem die '.RetryAsync (...)' -Pollys von Polly, die den 'onRetryAsync' -Parameter verwenden, nicht 'onRetry'. –

Antwort

1

Wenn die zurückgegebenen ApiException s aussagekräftige HttpStatusCode StatusCode Eigenschaften enthalten, könnten Sie sicherlich wählen, welche dieser StatusCodes einen erneuten Versuch verdienen; die Polly readme schlägt vor:

int[] httpStatusCodesWorthRetrying = {408, 500, 502, 503, 504}; 

Für ApiException s spezifisch auf die API aufgerufen, nur zu wissen, was diese API-spezifische Fehler darstellen, kann führen, ob sie erneut zu versuchen.

Wenn Sie sich für zu viele Ausnahmen entscheiden, sollten Sie einen Schutzschalter in Ihren PolicyWrap und nicht innerhalb des onRetry Delegaten der Wiederholungsrichtlinie einbinden. Polly bespricht 'Warum Circuit-Break?' here, und Links zu einer Reihe anderer Leistungsschalter Blog-Beiträge am Fuße der readme circuit-breaker section.