-
Notifications
You must be signed in to change notification settings - Fork 67
Add IHttpModule and pipeline infrastructure to emulate it #314
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
Conversation
...osoft.AspNetCore.SystemWebAdapters.CoreServices/HttpApplication/HttpApplicationMiddleware.cs
Outdated
Show resolved
Hide resolved
|
@davidfowl would you prefer to start without pooling? Any other concerns to get this in? |
|
To my mind, If it does need to be disabled (at least by default, hopefully with an opt-in mechanism) could we do some kind of factory, and be able to register the It could allow other (customer supplied) implementations too by inheriting a base class, perhaps to spin up x instances at startup and anything that goes through I don't want to make more work for you, and I want to see this next version get out (so we can get even more cool things added in), but if you are going to simplify this for the sake of maintainability/testability or otherwise, please make it a mechanism that can be overridden with a better implementation "at the consumer's risk". |
...pNetCore.SystemWebAdapters.CoreServices/HttpApplication/HttpApplicationPooledObjectPolicy.cs
Outdated
Show resolved
Hide resolved
| /// Gets or sets the number of <see cref="HttpApplication"/> retained for reuse. In order to support modules and appplications that may contain state, | ||
| /// a unique instance is required for each request. This type should be set to the average number of concurrent requests expected to be seen. | ||
| /// </summary> | ||
| public int PoolSize { get; set; } = 100; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the pool size on System.Web?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There doesn't appear to be a specified number. They create on demand, then this method is called when there's idle time to trim 3% of the pool on each call
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This kind of dynamic pool size doesn't seem easy to implement on top of ObjectPool<> as-is, although I did play around with a custom implementation that would use ML.NET and its forecasting APIs to dynamically adapt the target pool size based on the historical concurrent request count :)
|
@davidfowl anything else? |
This change adds support for
HttpApplicationandIHttpModuleand is emulated as best as possible on the ASP.NET Core pipeline. This is not tied to IIS and will work on Kestrel or any other host by using middleware to invoke the expected events at the times that best approximate the timing from ASP.NET Core. An attempt has been made to get the events to fire at the appropriate time, but because of the substantial difference between ASP.NET and ASP.NET Core there may still be unexpected behavior.In order to register either an
HttpApplicationorIHttpModuleinstance, use the following pattern:The normal
.UseSystemWebAdapters()middleware builder will enable majority of the events. However, the authentication and authorization events require two additional middleware calls in order to enable them if you want the events to fire in the expected order. If they are omitted, they will be called at the pointUseSystemWebAdapters()is added.When should this be used?
This is intended mostly for scenarios where a module needs to be run on ASP.NET Core but is unable to be migrated easily. Ideally, the code in a module should be restructured to be used as middleware. This is especially recommended when only a single or few events are used; those can usually be migrated in a straightfoward way.
However, if a module has many thousands of line of code and many events being used (the initial driver of this feature), this can provide a stepping stone to migrating that functionality to ASP.NET Core.
Emulated Events
The IIS event pipeline that is expected by
IHttpModuleandHttpApplicationis emulated using middleware by the adapters. As part of this, it will add additional middleware that will invoke the events. This is done via a feature that is inserted early on in the adapter pipeline. This exposes theHttpApplicationfor the request, as well as the ability to raise events on it.Events have a prescribed order which is replicated with these emulated events. However, because the rest of the ASP.NET Core pipeline is unaware of these events and so some of the state of the request may not be exactly replicated.
A common pattern is to be able to call
HttpRequest.End()orHttpApplication.CompleteRequest(). Both of these are supported, as well as continuing to raise the events that are raised in IIS with this (includingEndRequestand the logging events).HttpApplication lifetime
On ASP.NET Framework, each request would get an individual
HttpApplicationinstance. This object contains the following information:HttpApplicationtype itself or on registered modulesHttpApplicationinstance or its registered modulesIn order to support this, one of the first middlewares invoked will retrieve an instance of
HttpApplication. This uses aPooledObjectPolicy<HttpApplication>that will create an instance of the application'sHttpApplicationtype and register all modules on it. When the request is exiting that middleware, it will return theHttpApplicationinstance to the pool which will also remove theHttpContextinstance assigned to it.This can potentially create a number of instances of
HttpApplicationthat are only used a limited number of times. The pool can be controlled by customizing theHttpApplicationOptions.PoolSizeoption or providing a custom implementation ofObjectPool<HttpApplication>that can use thePooledObjectPolicy<HttpApplication>provided to override the pooling behavior.