I'm creating a ASP.NET .NET 4.0 website and part of this site requires that there is an "always running" application. Normally I would create a Windows Service for this, but the site will be hosted within a shared hosting environment, and unless I get a virtual server, then this isn't a possibility.
My first thought was to have a thread running in the background that would do this and it would be created on Application_Start and destroyed on Application_End. I've looked around and this seems like it could be an option, but I would of course have to hit the site in order to cause the Application_Start to be called and if the associated AppPool is recylced, then this process would have to be repeated (so I believe?!?).
Within a normal ASP.NET website does these seem possible?
In the end I had a seperate thread that sits and waits for a signal to be set. Once set it then does it's work. To make sure the thread is always active I make a HTTP request for a "dummy" page to ensure that, if the AppPool was recycled, then the Application_Start event is triggered and the thread restarted.
It depends on what mean by 'always running application':
If it's a realtime service, it still makes sense to run it as separate process, even if it may have a web front-end. It's so because ASP .NET server was designed by Microsoft for specific tasks(to run web apps, render pages etc.) in many aspects like memory usage or multithreading. And I'd prefer to use at least a VDS in such case.
Another case is when it's is a periodically(say every hour) alarmed application which does some uncomplicated work - perhaps your shared hoster has some mechanisms to trigger a specific page to do some work(as my hoster does). For example, I have an ASP .NET page that monitors the tour date list of my favourite band, and sends email notification when they are going to play a gig in my town - it's triggered by hoster every 4 hours.
Related
The goal is that I want my overall website response time to be instantaneous.
The problem is that I do no have IIS access, my website is hosted using external service and I have no control to the IIS panel.
My current approach now is having a scheduled code that keeps my website alive. The problem with this only approach is the hosting service has an algorithm to shutdown all their hosted website like every some hours.
This is why I need to implement another approach which to warm up / pre-load the website each time it runs.
How to do this when there is no access to the IIS panel?
The solution requires no 3rd party sites; robots; or apps, you merely write a very simple app yourself that periodically performs a trivial web function, perhaps a REST GET. By performing this function say every few minutes not only do you guarentee that the IIS pool won't timeout and be cold for a client, but it also has the nice effect of ensuring your website is up and running in a warm condition (JIT'd; and running) ready for a real request for your non-heartbeat website requests.
e.g.
In your website expose a REST API, say www.misspiggy.com/api/hiyaaaa that does nothing other than to return HTTP 200 OK.
By implemententing this in your ASP.NET app, any request to the above URL will cause your stopped or cold ASP.NET website to be JIT'd during:
first deployment (and even then only during a request is made to it)
after the IIS AppPool has timed out and needs to restart on demand
The client code that makes the REST request can be anything:
a console app
a Windows service
WinForms/WPF app
The console app can be triggered to fire via Windows Task Scheduler say every 5 minutes thus saving you the hastle of building in a scheduler.
My current approach now is having a scheduled code that keeps my website alive. The problem with this only approach is the hosting service has an algorithm to shutdown all their hosted website like every some hours
I suggest you set your ping period to be a matter of minutes rather than hours.
No admin access to server required
The problem is that I do no have IIS access, my website is hosted using external service and I have no control to the IIS panel
It should be pointed out that this solution does not require you to install anything new on the server nor make any changes on the server.
Azure
It is interesting to note that Azure Application Insights has Availability Tests that though designed for testing web site availability, can be used for this exact same purpose of keeping your website alive and warm ready to go for web clients. In fact this is what I do for my web apps.
Doing so keeps response times and latency as low as possible.
There are a number of things you can do but a real simple solution is to use a website monitoring site something like statuscake or uptime robot there are a large number of them out there. You set them up call a page or pages on your website at set intervals to ensure it is still up this has the added bonus of keeping the site warm.
I would also precompile your mvc app if you arent already doing that.
HTH
Once a day, I want my ASP.NET MVC4 website, which may be running on multiple servers, to email a report to me. This seems like a pretty common thing to want to do, but I'm having a tough time coming up with a good way to do it.
Trying to run a timer on a server to do this work is problematic for a couple of reasons. If I have multiple servers then I'd have the timer running on all of them (in case a server goes down); I'd need to coordinate between them, which gets complicated. Also, trying to access the database via Entity Framework from a background thread adds the complication that I must employ a locking strategy to serialize construction/disposal of the DbContext object between the periodic background thread and the "foreground" Controller thread.
Another option would be to run a timer on the servers, but to have the timer thread perform a GET to a magic page that generates and emails the report. This solves the DbContext problem because the database accesses happen in a normal Controller action, serialized with all of the other Controller accesses to the database. But I'm still stuck with the problem of having potentially more than one timer running, so I'd need some smarts in the Controller action to ignore redundant report requests.
Any suggestions? How is this sort of thing normally done?
You should not be doing this task from your web application as Phil Haack nicely explains it in his blog post.
How is this sort of thing normally done?
You could perform this task from a Windows Service or even a console application that is scheduled to run at regular intervals using the Windows Scheduler.
The proper solution is to create a background service that runs independently of your website. However, if that is not an option there is a hack where you can use the cache as explained in Easy Background Tasks in ASP.NET by Jeff Atwood.
A few options:
If you are hosting on Azure as a Website, check out WebJobs which was released recently in preview (http://azure.microsoft.com/en-us/documentation/articles/web-sites-create-web-jobs/)
If you don't want the pain of extracting out your email logic outside of the website, expose that functionality at a url (with a handler, mvc action, etc.) and then run a Windows Scheduled task that hits that url on a schedule.
Write a simple console app that is executed similarly via a Windows Scheduled task.
Or write a simple Windows Service that internally is looping and checking the time and when reached, hits that url, runs that exe, or has it's own code to send you the email.
I would recommend running Quartz.NET as a Windows Service:
Quartz.NET - Enterprise Job Scheduler for .NET Platform
There's boilerplate code for a Windows Service in the download.
Okay, so let's say I have a web application that absolutely has to perform some kind of startup and has to remain running indefinitely regardless of the communication it receives from the clients (as it's a push based system)
Now for testing I have been hosting this as a windows service, which is great because it allows for me to have a hard entry point to the application where I can do my bootstrapping and get the service up and running
Next, I'm trying to move this into the IIS world instead so I can face this service to the outside world...and I've hit a snag...I don't have any hard entry point where I can bootstrap the application except for global.asax, which as I understand it is only invoked when the clients make a call to the server
Is there a better area I can put an entrance to the application and get it bootstrapped without waiting for a client to connect to it? And is this area only called once or is it going to be called periodically as the application falls out of scope (so to speak)? Like I said, the app has to remain running at all times
Is there a better area I can put an entrance to the application and get it bootstrapped without waiting for a client to connect to it?
Yes, there is. You can warm up IIS.
And is this area only called once or is it going to be called periodically as the application falls out of scope (so to speak)?
It depends which method in Global.asax you use. Application_Start runs once per app start.
Like I said, the app has to remain running at all times
Beware, dragons here. This depends how critical it is. If you need utter reliability, you must use load balancer and have at least one other duplicate service. Other things to consider, app pool needs to be recycled from time to time. IIS, OS, your application have bugs, updates needs to be installed, network device fails, power outages do happen and so on.
Question: When a webapplication gets started, it executes Application_Start in global.asax.
Now, a web application gets started as soon as the first request for a page in that application reaches the server.
But my question is: how long will the application run until the application is stopped.
I mean when after the first page request, there's no traffic on the server.
I need to know because I intend to start a server that listens on a tcp port in global.asax.
And when the application stops, the server ceases to listen to its port.
It depends on your IIS settings. Your application will run in an application pool, which takes a bunch of settings defining the behaviour of this pool.
The thing you're looking for are recycling settings. In IIS 7, you can access these easily from the management console. Go to Application Pools, right click on the application pool your app runs in (if you don't know which one that is, then it's probably the DefaultAppPool) and select recycling.
Here you'll find the options you have to control the recycling behaviour of your app pool, which in turn controls when your app 'resets'.
in a word (well 2) - shared hosting.
on shared hosting beware, (godaddy/webhost4life etc) this timeout could well be less, plus you don't have option to configure that on these hosting environments. i've had cases where the app pool is recycled after 5 mins at certain peek times, so you might have to investigate 'wakeup' routines to poke your app to keep in in the memory. i do this for a few shared hosting apps to great effect using pingalive.com.
hope this helps, even if in an abstract way.
jim
Scenario: A WCF service receives an XDocument from clients, processes it and inserts a row in an MS SQL Table.
Multiple clients could be calling the WCF service simultaneously. The call usually doesn't take long (a few secs).
Now I need something to poll the SQL Table and run another set of processes in an asynchronous way.
The 2nd process doesn't have to callback anything nor is related to the WCF in any way. It just needs to read the table and perform a series of methods and maybe a Web Service call (if there are records of course), but that's all.
The WCF service clients consuming the above mentioned service have no idea of this and don't care about it.
I've read about this question in StackOverflow and I also know that a Windows Service would be ideal, but this WCF Service will be hosted on a Shared Hosting (discountasp or similar) and therefore, installing a Windows Service will not be an option (as far as I know).
Given that the architecture is fixed (I.E.: I cannot change the table, it comes from a legacy format, nor change the mechanism of the WCF Service), what would be your suggestion to poll/process this table?
I'd say I need it to check every 10 minutes or so. It doesn't need to be instant.
Thanks.
Cheat. Expose this process as another WCF service and fire a go command from a box under your control at a scheduled time.
Whilst you can fire up background threads in WCF, or use cache expiry as a poor man's scheduler those will stop when your app pool recycles until the next hit on your web site and the app pool spins up again. At least firing the request from a machine you control means you know the app pool will come back up every 10 minutes or so because you've sent a request in its direction.
A web application is not suited at all to be running something at a fixed interval. If there are no requests coming in, there is no code running in the application, and if the application is inactive for a while the IIS can decide to shut it down completely until the next request comes in.
For some applications it isn't at all important that something is run at a specific interval, only that it has been run recently. If that is the case for your application then you could just keep track of when the table was last polled, and for every request check if enough time has passed for the table to be polled again.
If you have access to administer the database, there is a scheduler in SQL Server. It can run queries, stored procedures, and even start processes if you have permission (which is very unlikely on a shared hosting, though).
If you need the code on a specific interval, and you can't access the server to schedule it or run it as a service, or can't use the SQL Server scheduler, it's simply not doable.
Make you application pool "always active" and do whatever you want with your threads.