Ihttpmodule ,Ihttphandler .NET - asp.net

I have some doubt over HttpModule and HttpHandler Please help me to clarify
1)In HttpModule I have noticed methods Init called only once . context_BeginRequest and context_EndRequest etc method calling for each request.
Is it guaranteed that for a module Init will call once for different users(or different request) and BeginRequest etc will call every time for different users (or different request) ?
2)Is there any possibility that Application_Start(global.asax) can run more than once because there may be more than one application object
3) Since application object can be different (from application pool) In this case how Application data is shared between different users?
4) In HttpHandler ProcessRequest method will call for each request (or for each user).
Thanks
Ritu

"Is it guaranteed that for a module Init will call once for different users(or different request) and BeginRequest etc will call every time for different users (or different request)?"
The init method will be called when the app pool starts / when the application is started for the first time. This is when the module is loaded.
The BeginRequest method is called every time the application starts handling a new HTTP request.
"2)Is there any possibility that Application_Start(global.asax) can run more than once because there may be more than one application object"
There is not more than one application in a particular folder. IIS doesn't work that way. Only one global.asax per application, and Application_Start will only be called once for each application unless the app pool is reset.
"3) Since application object can be different (from application pool) In this case how Application data is shared between different users?"
Depends where you're storing this application data and what you're using to retrieve it. I'm not sure what you mean about this. Session data should be scoped to an individual application (certainly for in-process session state server, and if properly configured also for out-of-process session state server)
"4) In HttpHandler ProcessRequest method will call for each request (or for each user)."
Yes, but only for requests which are mapped to your handler. Conversely, HttpModule can be called for ALL requests.

Related

First Web API request triggers execution of Application_Start

I'm having a Web application that also integrates a Web API. Just today I've found myself surprised to see that the first REST request on the Web API re-triggers the execution of Application_Start (although it has been run already when starting the web page). After reading ASP.NET HttpApplication lifecycle and ASP.NET Application Life Cycle Overview, it seems that the REST request is spawning a new HttpApplication.
Further, on the MSDN it says:
The first time that an ASP.NET page or process is requested in an application, a new instance of the HttpApplication class is created. However, to maximize performance, HttpApplication instances might be reused for multiple requests.
This sounds to me that each request could potentially spawn a new HttpApplication and that thus, Application_Start must be written in a re-entrant or idempotent way. Is this conclusion right?
In my concrete case, I'm initializing a log writer in Application_Start which fails the second time because the file is already being used. I guess in the case of an application pool recycling this wouldn't be a problem, as the resources are freed in-between.
You can read further down on the provided link
The Application_Start and Application_End methods are special methods that do not represent HttpApplication events. ASP.NET calls them once for the lifetime of the application domain, not for each HttpApplication instance.
So there is no need to write Application_Start in a re-entrant or idempotent way.
Furthermore Application_Start is not called on the recycling of IIS. It gets called on the first request after recycling when the application is actually loaded by IIS.
As for your error, make sure you're disposing off your logger on Application_End so the file handle gets released.

Akka.NET actor system in ASP.NET

I created a service with a RESTful API in ASP.NET, hosted in IIS. Inside this service, I would like to create an actor system with Akka.NET.
Upon creating the actor system:
var actorSystem = ActorSystem.Create("myActorSystem");
The following exception is thrown:
A first chance exception of type 'System.InvalidOperationException' occurred in System.Web.dll
Additional information: An asynchronous operation cannot be started at this time. Asynchronous operations may only be started within an asynchronous handler or module or during certain events in the Page lifecycle. If this exception occurred while executing a Page, ensure that the Page is marked <%# Page Async="true" %>. This exception may also indicate an attempt to call an "async void" method, which is generally unsupported within ASP.NET request processing. Instead, the asynchronous method should return a Task, and the caller should await it.
The actor system is inherently a concurrent system with asynchronous messages being exchanged between actors. As explained here, this actor system would not survive IIS taking down the AppDomain, which is probably why the aforementioned exception is thrown.
This article explains how to run background tasks in ASP.NET. However, I don't see how I could use this for my actor system, as I have no control over the lifecycle of background tasks that might be created by Akka.NET.
Is there a way to make this work, or should I abandon the idea of having an actor system in an ASP.NET application?
EDIT: I also saw a question on Stackoverflow about implementing a REST service using Akka. Any advice about a solution similar to the Spray toolkit, but working for Akka.NET would be welcome.
I've used Akka.NET and Akka.Remote inside ASP.NET MVC applications that are doing up to 1000 requests per second on EC2 - so I'll share some of the tips and tricks I used to get it up and running successfully. Had a prototype version that even used Akka.Cluster but ended up not shipping that version.
Best place to call ActorSystem.Create is inside Global.asax Application_Start().
Hang onto a static reference to the ActorSystem object inside Global.asax itself, using a static field or property. Helps ensure that the ActorSystem itself doesn't get garbage-collected in long-running applications.
Create a separate static helper class to initialize any top-level actors your applications needs - i.e. actors at the top of the /user/ hierarchy. This class should also provide actor paths that your ASP.MVC controllers and action methods can use for Tell and Ask operations.
Creating the ActorSystem is a bit of an expensive operation, because lots of system-level stuff gets fired up at once. It's definitely best to do this once at application startup and then just cache the result inside the Application class.
Creating individual actor instances is cheap - you should be able to do this no-problem inside ASP.NET MVC action methods. If you see this error come up again, please let us know what part in the request-handling process this error occurred and with which version of ASP.NET.
Edit: added some updated guidance for how to do this on ASP.NET Core
https://petabridge.com/blog/akkadotnet-aspnetcore/
Keep your ActorSystem as a shared property in some static class container - this way you may access it from the rest of your application. Actor system initialization/disposal can be done by:
Global.asax - use ActorSystem.Create(...) inside Global.asax Application_Start and dispose it with system.Shutdown() on Application_End.
OWIN - create actor system in OWIN's Startup.Configuration method and shut it down by binding to host.OnAppDisposing event (how-to link).
Remember that IIS will startup your web app only after first request and tear it down automatically after some time when it's idle. Therefore make sure, that your deployment script will ping application after publishing and set idle timeout (link) for long enough if you want your Akka actor system to run continuously.
Second option
Separate your Actor System logic and deploy it, for example, as a Windows Service (or Linux deamon). Turn on Akka.Remoting for it and create a proxy client, which will forward all application long-running sensitive tasks to external service. Similar solution is often used for things such as schedulers or event buses, when your application logic must be working continuously.

ASP.NET web application life-cycle/lifetime

In PHP (Apache + mod_php) the interpreter is restarted on every request. This is the execution model even if using PHP-fpm which keeps a few interpreters ready for requests.
Does an ASP.NET web app persist in IIS application pool waiting for requests or is there a new thread/process per request?
For example, would a static class variable persist across requests when one of those requests initializes it?
Yes, the value is persisted across requests.
A static class variable's (a field's) value is persisted and shared across all usage of the class (whether via an instantiated object or through the class reference itself). See http://msdn.microsoft.com/en-us/library/aa691162(v=vs.71).aspx

Integrated app pool, modules, and HttpApplication pipeline on IIS7.5

Given an application pool that runs on integrated mode, the apppool is able to provide service to "Managed Handler Requests" (GET an aspx page) as well as "non-Managed Handler Requests" (GET a jpg file).
When processing a MHR request the app pool should consider all modules but for nonMHRs should not consider the modules marked with the Managed Handler precondition.
Has the app pool two different HttpAplication pipelines (one for MHRs and the other for nonMHRs) ?
Or he only has one pipeline and is able to decide which httpAplication event handlers are raised depending of the request?
I guess the app pool decides if the request is managed or not, before httpApplication starts the BeginRequest. At least before the AuthenticateRequest. Is that right?
Response in the link:
All resources served by IIS are mapped to a handler in configuration. If the configuration mapping does not exist, requests for the resource will receive a 404 HTTP status. In addition to the configuration mapping, which takes place before the pipeline begins, the handler mapping can be changed during request execution ...
The Init function of the modules are only executed once (maybe in the application pool startup) independently of the Managed Handler precondition?
I guess the apppool doesn't create the whole pipeline (registering httpaplication events and so) for each request.
Thanks in advance,
UPDATE1: After reading the link I still "see" two diferent pipelines given a single apppool.
By diferent pipelines I mean two diferent sets of event handlers registered in the IIS pipeline:
BEGIN_REQUEST
AUTHENTICATE_REQUEST
AUTHORIZE_REQUEST
RESOLVE_REQUEST_CACHE
MAP_REQUEST_HANDLER
ACQUIRE_REQUEST_STATE
PRE_EXECUTE_REQUEST_HANDLER
EXECUTE_REQUEST_HANDLER
RELEASE_REQUEST_STATE
UPDATE_REQUEST_CACHE
LOG_REQUEST
END_REQUEST
When an application pool in integrated mode starts, it can look up the modules section and can execute the Init function of each module (indepentdently of the precondition setting). The Init function of each module registers itself in some IIS pipeline stages. But at runtime when processing non-managed requests it should skip the event handlers of modules with precondition managed handler. How can do that?
UPDATE2:
From my understanding, an app pool (the windows process) host an ASP.Net runtime (httpRuntime in System.Web?). This runtime contains a pool of httpApplication objects. When app pool starts (or maybe until first request arrive) several httpApplications are instantiated. At this time the Init method of the httpModules (under modules in web.config) are called.
Until IIS7 integration mode appearance I thought all httpApplication objects would be clones, but because depending of the type of handler's request (managed or non managed) some httpModules should be considered or not, I deduce that the httpRutime contains two httpApplication pools or maybe a given httpApplication object is only able to process managed handler requests or non-managed hadler requests, but never the two...
I think you can read this one
http://blogs.msdn.com/b/tmarq/archive/2007/08/30/iis-7-0-asp-net-pipelines-modules-handlers-and-preconditions.aspx
In there you see that the IIS has only one pipeline. The "classic" way of serving asp.net requests begins in the IIS pipeline’s EXECUTE_REQUEST_HANDLER event. Think of ASP.NET in classic mode as a pipeline within the IIS pipeline.
With the integrated mode you can basically plug in managed code in the whole IIS pipeline series of events, like adding asp.net forms authentication to static files like .jpg

Advanced: How many times does HttpModule Init() method get called during application's life?

Web application initialization is as follows:
As we know when IIS receives the first request for a particular Asp.net application resource, IIS creates an instance of a HttpApplication (defined in global.asax codebehind).
When this new instance is created it's initialization happens that also checks all configured HTTP modules.
All modules are then instantiated and put in the application's Modules collection (of type HttpModuleCollection)
modules are looped through and their Init() method is called (when they register for request events)
As far as I understand it the above scenario happens when a web application is started/initialized (hence application start event).
What happens with modules?
Are they (re)instatiated on each request or reused from the Modules property on each consecutive request while the web application is alive? As I understand IIS and Asp.net they are reused through the whole life of a web application.
If they are reused, can we assume that their Init() method is actually a pseudo event handler for application start event? The thing is we can't attach to application level events within http modules. But if they are being reused we could use Init() as application start event and do whatever we'd put in global.asax instead.
Question
Can we assume that module's Init() method is called only on application start event? Could we use this assumption to i.e. register routes for applications whose global.asax codebehind we can't change? web.config is usually accessible and we can change it the way we want.
Would this actually work?
Additional info
We can check HttpApplication code and check its InitModulesCommon() method. This one actually calls Init() of each registered HTTP module. What is more interesting is that this method is only used by InitIntegratedModules() and InitModules() methods. Which are both used only in HttpApplication.InitInternal() method. This is the basis of my assumptions, but I would like to know whether someone has abused IHttpModule.Init() for application start event.
Init() is called only once (per HttpApplication instance)
After I tested this the inner workings of IHttpModule initialization are as follows:
Every IHttpModule is initialized at web application start by instatiating and a call to Init() method
HttpApplication stores all module instances in its Modules property
Modules are then reused for the whole life of an HttpApplication and are not discarded/reinitialized as long as the application is alive
So the best outcome is
You can't attach an IHttpModule to application level events, but you can use its Init() method as pseudo application start event delegate. Inside it you can execute any code that you'd usually put inside Application_Start delegate in your Global.asax.
You can also read detailed information about it in my blog post.
But be careful in real-life web server environment
But IIS uses something called application pools. And each pool can have an arbitrary number of HttpApplication instances. Yes multiple. Application starting creates all these instances. Every one of them initializes their own list of modules but only the first one executes the Application_OnStart event handler.
So whenever your module modifies some common shared resource, you should take extra measures to indicate that the first module has done that and others won't do it again. Read an additional blog post about it that will show you how and when to use thread locking with your module to make it actually act as an Application_OnStart event handler. BTW: It's also possible to handle Application_OnEnd event if you need to. ;)
Detailed blog post links
Writing a custom IHttpModule that handles Application_OnStart event
How to correctly use IHttpModule to handle Application_OnStart event
Application_Start is only run once for the lifetime of your application.
IHttpModule.Init is run for each instance of HttpApplication, before request processing begins. See the walkthrough. Init is where you can register events used to process the request.
An instance of HttpApplication can be reused for multiple requests. ASP.Net pools HttpApplication objects, so the Init will be called once for every new instance of HttpApplication

Resources