diff --git a/RiotSharp/Http/RateLimitedRequester.cs b/RiotSharp/Http/RateLimitedRequester.cs index 1016b831..8be1af91 100644 --- a/RiotSharp/Http/RateLimitedRequester.cs +++ b/RiotSharp/Http/RateLimitedRequester.cs @@ -19,19 +19,21 @@ public class RateLimitedRequester : RequesterBase, IRateLimitedRequester public readonly IDictionary RateLimits; private readonly bool _throwOnDelay; + private readonly int _retryCount; private readonly ConcurrentDictionary _rateLimiters = new ConcurrentDictionary(); /// - public RateLimitedRequester(string apiKey, IDictionary rateLimits, bool throwOnDelay = false) : base(apiKey) + public RateLimitedRequester(string apiKey, IDictionary rateLimits, bool throwOnDelay = false, int retryCount = 3) : base(apiKey) { RateLimits = rateLimits; _throwOnDelay = throwOnDelay; + _retryCount = retryCount; } #region Public Methods /// - public Task CreateGetRequestAsync(string relativeUrl, Region region, List queryParameters = null, + public Task CreateGetRequestAsync(string relativeUrl, Region region, List queryParameters = null, bool useHttps = true) { var host = GetPlatformHost(region); @@ -66,7 +68,7 @@ public async Task CreatePutRequestAsync(string relativeUrl, Region region, var response = await SendAsync(request).ConfigureAwait(false); response.Dispose(); return true; - + } catch (RiotSharpException) { @@ -93,12 +95,30 @@ private RateLimiter GetRateLimiter(Region region) /// The region which's requests should be rate limited private async Task GetRateLimitedResponseContentAsync(HttpRequestMessage request, Region region) { - await GetRateLimiter(region).HandleRateLimitAsync().ConfigureAwait(false); + var numRetries = 0; + Exception lastException = null; - using (var response = await SendAsync(request).ConfigureAwait(false)) + while (numRetries < _retryCount) { - return await GetResponseContentAsync(response).ConfigureAwait(false); + await GetRateLimiter(region).HandleRateLimitAsync().ConfigureAwait(false); + try + { + using (var response = await SendAsync(request).ConfigureAwait(false)) + { + return await GetResponseContentAsync(response).ConfigureAwait(false); + } + } + catch (RiotSharpRateLimitException e) + { + lastException = e; + GetRateLimiter(region).SetRetryAfter(e.RetryAfter); + request = request.Clone(); + numRetries++; + continue; + } } + + throw lastException; } } } diff --git a/RiotSharp/Misc/HttpRequestMessageExtensions.cs b/RiotSharp/Misc/HttpRequestMessageExtensions.cs new file mode 100644 index 00000000..523650c9 --- /dev/null +++ b/RiotSharp/Misc/HttpRequestMessageExtensions.cs @@ -0,0 +1,18 @@ +using System.Net.Http; + +namespace RiotSharp.Misc +{ + public static class HttpRequestMessageExtensions + { + + public static HttpRequestMessage Clone(this HttpRequestMessage req) + { + var newReq = new HttpRequestMessage(req.Method, req.RequestUri); + foreach (var header in req.Headers) + { + newReq.Headers.Add(header.Key, header.Value); + } + return newReq; + } + } +} \ No newline at end of file