-
Notifications
You must be signed in to change notification settings - Fork 10.3k
[Epic] Request Throttling and Queuing Middleware #10702
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
OnRejected
callback to Request Queuing middleware to allow user code to handle rejections
#10707
Can we get some cool info about what this is and how it be what it do? |
The cliff's note's versions is that this middleware is designed to prevent threadpool starvation just like the System.Web request queue. It will be able to enforce a configurable concurrent request limit and start queuing new requests once the concurrent request limit is reached. Of course, the number of requests that can be queued at once is also configurable. If the request queue fills up, requests will be rejected with a generic 503 or custom handler. There's still discussion on how useful it might be to allow certain (e.g. admin) requests to bypass the main request queue. That's what "Multiple queues and queue assignment. (Func<HttpContext, Queue>)" is referring to. Whether we just blog about this middleware, include it in some templates, or something else is still up in the air. I doubt it's something we'd be able to turn on by default. |
Of course, things have changed from the early days of System.Web. Most importantly, a request doesn't necessarily block a thread, but sometimes they do. |
This is also something I deffo remember discussing in the early days of K. For whatever reason we didn't built it in, but there was discussion about making this an MVC filter - (middlware is a better choice).
If you end up having this feature, I'd suggest showing a sample that does that based on endpoints and metadata. Then you can slap an attribute on a method to configure the policy. You might also want to write a generic |
Multiple queues are a 💪 stretch goal right now anyway :). But this is good stuff to consider when we get there. |
Will it be possible to say, add the Queing middleware after Authentication middleware? So for example, authenticated user traffic could be prioritised? If user name = "dazinator" he always gets to skip the queue ? ;-) |
If we reach our stretch goal and get multi-queue support, that should be possible. |
Do you also have plans to add throttling based on time like https://github.com/stefanprodan/AspNetCoreRateLimit? for example a user can call a api 10 times per second. and as @rynowak mentioned it would be a good feature to wire up these middlewares to endpoint metadata |
Our plans (for now) are limited to what you see above :). Simple front-door queueing is what we're starting with, we do have some ideas around integrating throttling moving forward but that may also end up as a separate middleware. |
Closing for now, we don't have plans to go further here in 5.0. Individual work items are still on the backlog. |
Optimistically putting this in 3.1, but no committments as to when exactly this ships. It won't be part of 3.0.
This is tracking work to add a Request Throttling and Queuing middleware (or possibly middlewares) to ASP.NET Core. The purpose of this is to enable app developers to restrict the number of concurrently-running requests in their application in order to better manage resources.
Currently, the only queuing that occurs in ASP.NET Core applications is through use of the thread-pool queue, which queues completions of async operations (i.e.
async
/await
) and other thread-pool work items. This can be difficult to manage and measure. For some applications, the introduction of a concurrent request limit can mitigate issues caused by problematic async patterns (like "sync-over-async" where blocking calls are done inasync
code paths). The "Right Thing" to do in most of these cases is to unravel these "sync-over-async" calls into a trueasync
/await
pattern, but sometimes that's infeasible or too costly. Limiting concurrent requests conserves these resources.When there is a concurrent request limit, it is also desirable to "queue" requests that come in over this limit rather than turning them away immediately. This also provides a clear metric to use to measure the impact of load on your system (the number of requests waiting in the queue).
Our goal is to build a middleware that limits the number of concurrently executing requests in the remainder of the pipeline. The middleware will also queue requests beyond that limit until there is space. Finally, if the limit and the queue are exhausted, it will reject the request immediately (usually by emitting a 503 HTTP status code).
We do believe that components of this middleware may be useful for "throttling" as well. Throttling includes scenarios like API Rate Limits, where requests are tracked against certain per-user limits and rejected when they exceed that limit. This is beyond the current scope of the middleware but may serve as a stretch goal.
NOTE: This is our summer intern project, so bear with us as we work through it. We've shipped many of our intern projects as production code in future releases and intend to do so with this one as well!
Child Items:
dotnet-counter
tool to view them.OnRejected
callback to Request Queuing middleware to allow user code to handle rejections #10707OnRejected
callback to allow user code to handle requests rejected due to insufficient queue space.Func<HttpContext, Queue>
, 💪 stretch goal)The text was updated successfully, but these errors were encountered: