IIS module: Init() is called only once in a website? - iis

I need to add an IIS module for some processing. Here is my module:
namespace MyNamespace
{
public class MyModule : IHttpModule
{
#region IHttpModule Members
public void Dispose()
{
}
public void Init(HttpApplication context)
{
//I hope to do some work here ONLY once for all requests
context.ReleaseRequestState += new EventHandler(myHandler);
}
#endregion
public void myHandler(Object source, EventArgs e)
{
//do some work...
}
}
}
I need to do some resources-consuming work in the Init() method. I HOPE that Init is called ONLY once in a website and is called again only when the website is restarted in IIS Manager.
Can an expert in this tell me whether Init() works as I hope for?
Thanks!

For ANY requests being carried out, it will always call this method so no, it is not for the first time the app pool spins up. What you may wish to do is have a static variable in there to see if it truly is the first time its been hit and if not, carry on with what you need otherwise ignore it. ensure you lock around the portion of code when you are setting the variable to true.
Remember, IIS has application pools which websites use (generally speaking). There will be multiple concurrent requests coming into IIS to process and what happens? The app pool executes to serve the request to the website therefore multiple "hits" will be executed for the Init() for the HttpModule but once per application, if that makes sense.
Every one of them initializes their own list of modules.
you DO have the option of using the Application_Start event in the global asax which will only ever execute once per application (when the app pool spins up and the request is being submitted) - perhaps you can use this for your needs, which would be a better option.

Related

Does recycle call Startup.Configuration?

Is the following code called after recycle when hosted in IIS:
[assembly: OwinStartup(typeof(xxx.Startup))]
public class Startup
{
public void Configuration(IAppBuilder app)
{
}
}
Yes, recycling works similary to "Reset", with the difference of first starting a new worker process and then shuting down the old in an attempt to keep the website availible for requests. It also tries to transfer the old requests to new process.
Good Article on this topic: https://fullsocrates.wordpress.com/2012/07/25/iisreset-vs-recycling-application-pools/

Why route table filling happens in first request of MVC application

For a MVC 5 application, when I debug the solution, then only on first request, break point hits the RouteConfig class, next request on wards, it's not filling the route table again.
Question, where the routing table stored, how it will match on second request?
Thanks,
The RouteTable is implemented as a singleton. In ASP.NET (or MVC), a singleton's lifetime lasts until the application pool is recycled.
namespace System.Web.Routing
{
using System;
using System.Runtime.CompilerServices;
[TypeForwardedFrom("System.Web.Routing, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35")]
public class RouteTable
{
private static RouteCollection _instance = new RouteCollection();
public static RouteCollection Routes
{
get
{
return _instance;
}
}
}
}
So all web requests will use the same instance of the RouteTable, first, second, or otherwise.
The RouteTable is automatically repopulated when the application pool recycles because it is initialized within the Application.Start event (usually in Global.asax). This event only fires 1 time when the application first starts (or when the application pool recycles).

Threads in JSF?

I new in JSF, and I need use Threads for google maps. I am using primefaces for google maps, but I need excute a thread in background to get lat and long from data base and then graphic the markers in the map.
Your question is not specific to JSF, but rather to web applications in general. So, how to perform tasks asynchronously in a Java web applications? Definitely NOT by creating your own threads.
A Java web application runs in an application server (for example jBoss). It is the responsibility of the application server to manage Java threads for you. For instance, it will use a separate thread for each web request that comes in. The application server creates a pool of threads and reuses those threads since it is somewhat expensive to create new ones all the time. That's why you should not create your own, especially if it's done for every web request since it will directly impact scalability.
In order to execute tasks asynchronously, you can use the ejb #Asynchronous annotation (assuming the app is running in a Java EE container like jBoss, but not Tomcat).
import javax.ejb.Singleton;
#Singleton
public class AsyncBean {
#Asynchronous
public void doSomethingAsynchronously() {
// when this EJB is injected somewhere, and this method is called, it will return to the caller immediately and its logic will run in the background
}
}
If the app is not running in a Java EE container, take a look at this answer which nicely lays out some other options for async processing in web apps.
JSF is completely unrelated to your problem. For this case, JSF will act as mere HTML generator. Your specific problem is how to prepare data asynchronously and consume it from your web app.
You can create the thread manually when the application starts on a class that implements ServletContextListener interface, like this:
public class ApplicationListener implements ServletContextListener {
ExecutorService executor;
public ApplicationListener() {
executor = Executors.newSingleThreadExecutor();
}
#Override
public void contextInitialized(ServletContextEvent sce) {
Runnable task = new Runnable() {
#Override
public void run() {
//process the data here...
}
}
executor.submit(task);
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
executor.shutdownNow();
}
}
Improve the design above to fulfill your requirements. Take into account that creating threads in an application server should only be done if you know what you're doing.
Another implementation would be to use another application to do the processing (let's call it Data Processor), which by default will run on a separate thread and environment. Then, communicate your web application with this Data Processor through a cache or nosql application like EhCache, Infinispan or Hazelcast.

Force Application Start on Azure Web Role

I have a web role on azure and I would like to force a Application_Start without waiting for the first request.
I managed to set the "Start Automatically" property to true on my site
AutoStart a WCF on Azure WebRole
But the Application_Start is not called until the first request comes.
I don't know exactly if I am missing something important here. The server is a W2008 R2 and the IIS version is 7.5
Thanks!
SOLUTION
I put the solution code here. I hope will help someone. I just added a WebRole.cs and just put that code to perform a ping every 30 seconds. Please netice I'm browsing Service.svc because this is my endpoint, your endpoint could be another one. Notice I'm asking for "Endpoint1". If you have more than one endpoints, you should review that line.
public class WebRole : RoleEntryPoint
{
public override void Run()
{
var localuri = new Uri( string.Format( "http://{0}/Service.svc", RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["Endpoint1"].IPEndpoint ) );
while (true)
{
try
{
var request = (HttpWebRequest)WebRequest.Create(localuri);
request.Method = "GET";
var response = request.GetResponse();
}
catch { }
System.Threading.Thread.Sleep(30000);
}
}
public override bool OnStart()
{
return base.OnStart();
}
}
The IIS will only start when the first request arrives. The workaround is to send an HTTP request to the same VM from within OnStart or your RoleEntryPoint descendant - that's easy using WebRequest or equivalent class.
Jordi, I've recently experienced the same issue.
Based on my test Application_Start() is called ONLY when the 1st request ISS for the WebApp. (if you try to start VS in Debug without it open any page (see options in proj/debug), you will see that Application_Start() won't be called also if you don't run the WebApp in Azure)
I suppose that you need doing somethings when the WebRole start, well put your code in the WebRole.cs ;)
Here you can override OnStart() and OnStop() and put your code that wiil be execuded when the WebRole will start.
I've used this way to run a BakgroundWorker that do some scheduled tasks, independently from IIS.
I hope this help.
Davide.
Note:
1 - if you dont'have a WebRole.cs create it in the root of project and write inside:
public class WebRole : RoleEntryPoint
{
public override bool OnStart()
{
...your code...
return base.OnStart();
}
}
2 - If you need to debug the code mind that you need to run VS in debug with the Azure project that refer to WebApp as a "Run Project", otherwise the WebRole will not be called
You could try putting some code in your WebRole.cs to request some URLs from your website. I've tried that, and it seems to work somewhat. But it's a pain to debug, so I never got it really nailed down.
Another option would be to use IIS Application Initialization. You can't use it on IIS 7.5, but you can get IIS 8 if you upgrade your roles to Windows 2012 (set osFamily="3" in your .cscfg).

Why is my static constructor called twice in an Azure Web Role?

I'm trying to initialise my dependency registration for a WCF service running in an Azure Web Role, but I'm seeing a very unusual behaviour whereby the static constructor of my class is being invoked twice.
This is the Dependencies class I'm using as a registry point for the dependencies of the application.
public static class Dependencies
{
private static IUnityContainer container;
static Dependencies()
{
Dependencies.container = new UnityContainer();
}
public static IUnityContainer Container
{
get
{
...
}
set
{
...
}
}
public static void ConfigureContainer()
{
var container = new UnityContainer();
// Configure container.
Dependencies.container = container;
}
}
In my overload of RoleEntryPoint.OnStart(), I make a call to a static ConfigureContainer method to set up the container with my dependencies registered:
public override bool OnStart()
{
// Configure container for dependency resolution.
Dependencies.ConfigureContainer();
return base.OnStart();
}
My expectation is that the static members of the Dependencies class should be initialised by this code and will be available to the components of the application.
What I'm seeing (using a breakpoint and the VS2012 debugger) is that the static constructor of Dependencies is being called twice: once during the original initialisation of the application and again during first request to the service. Subsequent requests don't invoke the static constructor (as expected).
I'd love to hear an explanation of why the runtime is behaving this way and what I should be doing instead to produce my static registry of dependencies.
It's likely because when you host a webrole in full IIS, the RoleEntryPoint code and the rest of the web application run in different AppDomains.
http://blogs.msdn.com/b/windowsazure/archive/2010/12/02/new-full-iis-capabilities-differences-from-hosted-web-core.aspx
By default you use "full IIS" mode in a web role and you get two processes - IIS worker process for handling HTTP requests and role worker process for running RoleEntryPoint descendant code. Depending on how your code is designed you may end up using that static constructor in both processes and then it'll be invoked twice.

Resources