Last active
February 1, 2018 17:22
-
-
Save kierenj/a21a0d23cac162c8332f3d65266213eb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class MyLimitedApiClient | |
{ | |
private static readonly object _syncRoot = new object(); | |
private DateTime? _nextRequestTimeSlot = null; | |
private readonly HttpClient _http; | |
private static readonly TimeSpan RateLimitedInterval = TimeSpan.FromSeconds(0.1); // 10 per sec | |
public async Task<T> GetJson<T>(string url) where T : class | |
{ | |
var serialiser = new DataContractJsonSerializer(typeof(T)); | |
retry: // just for the "goto" controversy! | |
DateTime slot; | |
lock (_syncRoot) | |
{ | |
slot = _nextRequestTimeSlot ?? DateTime.UtcNow; | |
_nextRequestTimeSlot = slot + TimeSpan.FromSeconds(RateLimitedInterval); | |
} | |
var toWait = (slot - DateTime.UtcNow).TotalSeconds; | |
if (toWait > 0) | |
{ | |
// wait with a super-efficient async delay | |
await Task.Delay((int)(toWait * 1000)); | |
} | |
// do the request! | |
var response = await _http.GetAsync(url, HttpCompletionOption.ResponseHeadersRead); | |
// check for limited response | |
var limited = response.StatusCode == (System.Net.HttpStatusCode)429; | |
if (limited) | |
{ | |
// get a new slot | |
goto retry; | |
} | |
// read the response.. as an example, we'll deserialise as an object | |
using (var stream = await response.Content.ReadAsStreamAsync()) | |
{ | |
var result = serialiser.ReadObject(stream) as T; | |
return result; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment