简体   繁体   中英

Polly retry with different url

I am trying to create a solution with polly where I request an other api.
I have a list of URLs to multiple instances of the same service.
I want that when the first request failes, an other should automaticly start with the next url from my list.

Here is an example where i try this behaviour with two static addresses
The Problem with this solution is that the url does not change until i start the next request. I want that the urls changes on every retry

 public static void ConfigureUserServiceClient(this IServiceCollection services)
    {

        _userServiceUri = new Uri("https://localhost:5001");

        services.AddHttpClient("someService", client =>
        {
            client.BaseAddress = _userServiceUri;
            client.DefaultRequestHeaders.Add("Accept", "application/json");
        }).AddPolicyHandler(retryPolicy());
    }

    private static IAsyncPolicy<HttpResponseMessage> retryPolicy()
    {
        return Policy.HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.RequestTimeout)
            .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(retryAttempt),
            onRetry: (result, span, ctx) =>
            {
                _userServiceUri = new Uri("https://localhost:5002");
            });
    }

You should consider to use the Fallback policy instead.

Like this:

private static HttpClient client = new HttpClient();
static async Task Main(string[] args)
{
    var addressIterator = GetUrls().GetEnumerator();

    var retryLikePolicy = Policy<string>
        .Handle<HttpRequestException>()
        .FallbackAsync(fallbackAction: async (ct) =>
        {
            if (addressIterator.MoveNext())
               return await GetData(addressIterator.Current);
            return null;
        });

    addressIterator.MoveNext();
    var data = await retryLikePolicy.ExecuteAsync(
       async () => await GetData(addressIterator.Current));

    Console.WriteLine("End");
}

static async Task<string> GetData(string uri)
{
    Console.WriteLine(uri);
    var response = await client.GetAsync(uri);
    return await response.Content.ReadAsStringAsync();
}

static IEnumerable<string> GetUrls()
{
    yield return "http://localhost:5500/index.html";
    yield return "http://localhost:5600/index.html";
    yield return "http://localhost:5700/index.html";
}

Please note that this code is just for demonstration.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM