Skip to content

Instantly share code, notes, and snippets.

@kevingosse
Last active July 7, 2020 01:52
Show Gist options
  • Save kevingosse/0fee440da520e4845681969d1d07c0be to your computer and use it in GitHub Desktop.
Save kevingosse/0fee440da520e4845681969d1d07c0be to your computer and use it in GitHub Desktop.
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