public async Task evicts_handlers_after_timeout() { var createdHandlers = new List <HttpMessageHandler>(); HttpMessageHandler createHandler() { var handler = new DelegateHandler((message, token) => Task.FromResult(new HttpResponseMessage())); createdHandlers.Add(handler); return(handler); } var factory = new RoundRobinHttpClientFactory(1, createHandler, TimeSpan.FromSeconds(5)); var clients = Enumerable.Range(0, 10).Select(i => factory.GetClient()).ToList(); clients.Count.ShouldBe(10); createdHandlers.Count.ShouldBe(1); await Task.Delay(TimeSpan.FromSeconds(6)); clients = Enumerable.Range(0, 10).Select(i => factory.GetClient()).ToList(); clients.Count.ShouldBe(10); createdHandlers.Count.ShouldBe(2); }
async Task CreateAndDisposeClientWithGarbageCollection(RoundRobinHttpClientFactory factory, Func <HttpClient, Task> clientInvoker = null) { var client = factory.GetClient(); if (clientInvoker != null) { await clientInvoker(client); } client.Dispose(); }
public void creates_as_many_handlers_as_requested_count() { var createdHandlers = new List <HttpMessageHandler>(); HttpMessageHandler createHandler() { var handler = new DelegateHandler((message, token) => Task.FromResult(new HttpResponseMessage())); createdHandlers.Add(handler); return(handler); } var factory = new RoundRobinHttpClientFactory(5, createHandler, Timeout.InfiniteTimeSpan); var clients = Enumerable.Range(0, 10).Select(i => factory.GetClient()).ToList(); clients.Distinct().Count().ShouldBe(10); createdHandlers.Count.ShouldBe(5); }
public async Task evicts_503_handlers_temporarily() { var activeHandler = new DelegateHandler((message, token) => Task.FromResult(new HttpResponseMessage { StatusCode = HttpStatusCode.OK, Content = new StringContent("active") })); int timedOut = 0; var retryHandler = new DelegateHandler((message, token) => { if (Interlocked.Exchange(ref timedOut, 1) == 0) { return(Task.FromResult(new HttpResponseMessage() { StatusCode = HttpStatusCode.ServiceUnavailable, Headers = { RetryAfter = new RetryConditionHeaderValue(TimeSpan.FromSeconds(5)) } })); } return(Task.FromResult(new HttpResponseMessage() { StatusCode = HttpStatusCode.OK, Content = new StringContent("reactivated") })); }); var handlerIndex = 0; var factory = new RoundRobinHttpClientFactory(2, () => handlerIndex++ *2 == 0 ? activeHandler : retryHandler); var responsesBefore = await execute(); await Task.Delay(TimeSpan.FromSeconds(6)); var responsesAfter = await execute(); responsesBefore.Count(r => r.response.StatusCode == HttpStatusCode.ServiceUnavailable).ShouldBe(1); responsesBefore.Any(r => r.content == "reactivated").ShouldBeFalse(); responsesAfter.All(r => r.response.StatusCode == HttpStatusCode.OK).ShouldBeTrue(); responsesAfter.Count(r => r.content == "reactivated").ShouldBe(5); responsesAfter.Count(r => r.content == "active").ShouldBe(5); async Task <List <(HttpResponseMessage response, string content)> > execute() { List <(HttpResponseMessage httpResponseMessage, string content)> response = new List <(HttpResponseMessage httpResponseMessage, string content)>(); for (int i = 0; i < 10; i++) { using (var client = factory.GetClient()) { var httpResponseMessage = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, "http://nowhere.example/path")); var content = httpResponseMessage.Content == null ? null : await httpResponseMessage.Content?.ReadAsStringAsync(); response.Add((httpResponseMessage, content)); } } return(response); } }