I have one API endpoint that needs to return to the caller as soon as possible. It currently returns under 1ms. If, however, I log some stuff to the database it now takes closer to 10ms.
How would you approach completing the request and then doing some kind of processing after the request was completed? I tried with Response.Body.Flush(), but that doesn't complete the request and it still takes the full 10ms. It looks like it's sending/flushing the payload, but the request still doesn't complete until the action method is completed.
Would it work to do the logging in a middleware?
EDIT:
One workaround that I found was to use FluentScheduler like this:
JobManager.Initialize(new Registry());
JobManager.Start();
in Program.cs before host.Run() and then schedule an immediate task from an action like this:
JobManager.AddJob(() =>
{
// do something...
}, (s) => s.ToRunOnceIn(1).Seconds());
Async is the correct way to solve this problem. During your request (whenever you want) start an async connection/query to the database. Just don't wait for it to finish.
Logging in middleware won't help you, as you will still be within the request pipeline and you may or may not have the necessary information to log what you need to do.
You could log asynchronously, which would probably give you the biggest improvement without major architectural changes: Async Programming : Introduction to Async/Await on ASP.NET
If that doesn't work, you can do something that is multithreaded. That gets more complicated, but it is still doable: Multithreading in C# .NET 4.5 (Part 1)
This is just a thought, so don't down-vote if I'm way off. Could you use
HttpResponse.RegisterForDispose()
? For example:You need to start somehow a different thread. A middleware put in front of the pipeline will give you the chance to do work just before the request completes. If you spin a thread, from there, then it might work.
You probably want to use some sort of producer-consumer pattern so you don't kill your server. Otherwise, if every request starts a thread that does work immediately and you have many requests at the same time, you might end up running out of resources. A producer-consumer would help you throttle that work.
If you're not in a hurry, you can wait another week or so when I'll deliver the file logger for ASP.NET and then you'll see a similar implementation there.