Last active
July 7, 2020 01:52
-
-
Save kevingosse/0fee440da520e4845681969d1d07c0be 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
using System; | |
using System.Net.Http; | |
using System.Threading; | |
using System.Threading.Tasks; | |
using Microsoft.AspNetCore.Builder; | |
using Microsoft.AspNetCore.Hosting; | |
using Microsoft.AspNetCore.Http; | |
namespace KestrelTimeout | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
var webhost = new WebHostBuilder() | |
.UseKestrel() | |
.UseSockets() | |
.UseUrls("http://*:9000") | |
.UseStartup<Startup>() | |
.Build(); | |
webhost.Start(); | |
Task.Run(Client); | |
Console.ReadLine(); | |
} | |
static void Client() | |
{ | |
int id = 0; | |
var httpClient = new HttpClient(); | |
while (true) | |
{ | |
try | |
{ | |
var currentId = Interlocked.Increment(ref id); | |
var request = new HttpRequestMessage { RequestUri = new Uri("http://localhost:9000/") }; | |
request.Headers.Add("id", currentId.ToString()); // Send the id in the header | |
var response = await httpClient.SendAsync(request); | |
var content = await response.Content.ReadAsByteArrayAsync(); | |
if (content.Length >= 4) | |
{ | |
var responseId = BitConverter.ToInt32(content); | |
// Check that we got the same id back | |
if (currentId != responseId) | |
{ | |
Console.WriteLine("Id mismatch! {0}, {1}", currentId, responseId); | |
} | |
} | |
} | |
catch | |
{ | |
} | |
} | |
} | |
} | |
class Startup | |
{ | |
public void Configure(IApplicationBuilder app) | |
{ | |
app.Run(ProcessRequest); | |
} | |
private Random _rnd = new Random(); | |
private int GetNext() | |
{ | |
lock (_rnd) return _rnd.Next(0, 100) - 50; | |
} | |
private async Task ProcessRequest(HttpContext context) | |
{ | |
var timeout = Task.Delay(200 + GetNext()); | |
var process = Task.Run(() => HandleRequest(context)); | |
var t = await Task.WhenAny(timeout, process); | |
if (t == timeout) | |
{ | |
// In case of timeout, set the status code and return | |
context.Response.StatusCode = 503; | |
} | |
} | |
private void HandleRequest(HttpContext context) | |
{ | |
// Read the id early on | |
var id = context.Request.Headers["id"]; | |
// Simulate some processing | |
Thread.Sleep(200 + GetNext()); | |
// Reply with the same id. | |
// At this point, if ProcessRequest already returned, context.Response can be the response of the next request! | |
context.Response.Body.Write(BitConverter.GetBytes(int.Parse(id))); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment