Is there a way to host an ongoing process in IIS? Let's say i'm writing an invoicing web site and every so often I need to send out scheduled invoices. This is really part of my invoicing app and I'd like it to be deployed as part of my invoicing app, by copying files to the web server. I don't want the deployment headaches or the awkward separation that would come with writing this as a Windows Service. Is there a way this can be done in IIS?
Probably your simplest solution would be to develop a simple console EXE that does its thing and you schedule it in Scheduled Tasks. Updates to the EXE are done the same way as the web app, just overwrite the file.
Take a look Best way to run scheduled tasks, it'd probably fit your use case.
Related
I use Visual Studio 2013's "Publish" and Web Deploy to publish my Asp.Net MVC 5 website. However when I update my website, it won't work during the upload. I'm looking for a way to minimize the downtime of the website during the update. The website is running in a VPS and I have full access to it. One solution that came to my mind is to configure the Web Deploy to first put the uploaded files to a temporary folder and once the upload is finished, it should then replace the new files. This would make the update a few seconds tops. I can do this manually but that's not an elegant way to update one's website.
PS: Maybe there are better ways to update the website but so far I like the web deploy. It's much faster than FTP for instance.
One of the most interesting things I've seen is to have two websites. Only one of them is running at a time. After finishing the upload, you disable the active one, and enable the one you uploaded too.
This works well if both are in the same Application Pool and even works with sessions if you want (how to: Configure SQL Server to Store ASP.NET Session State).
I've never done it this way, seems a little to complex for the minimal down time there actually is, but it's one way.
Here's the solution that we use on a high traffic website with 4 web servers.
1) Files are moved to the server into /site/version-xxx
2) IIS Web Application is re-pointed to the new version.
All this is automated and synchronized across the web servers. The end user doesn't notice any difference. (we don't rely on sessions to persist the user experience, if sessions is a must for you and you don't want to interrupt them, then you need to consider to store them on an external system that will not flush them when the websites are repointed).
This approach also allows us to rollback to any previous version.
We have DLLs that contain hundreds of custom client processes that are kicked off from an ASP.NET application. Our clients run these processes while performing data entry, and typically there's only 1 process per client. On any given day, we might update 2 or 3 of these processes.
Currently these are all housed in a series of DLLs, which means that we are publishing our application a couple times per day. As a result, any logged-in clients get booted out of the system since the publish causes an app restart.
Is there a way that we can update these DLLs without requiring a full publish each time?
If your client processes have a common API then you could host, the DLLs separately in a WCF (or similar) service, and call the client processes remotely. So basically, consider moving to a service oriented architecture.
Check out the Managed Extensibility Framework (MEF) from Microsoft. It provides not only dependency management but also plug-in like library loading. Most likely it's exactly what you're looking for.
You can switch to SQL server or state server sessions in order to perserve session and logged users after app restart. Or store these dlls in APP_DATA and load it dinamically. Then of course you have to think of some refreshing system and refresh loaded dlls with newly uploaded ones.
There is no sensible way to avoid an application restart. Please note the emphasis on the word sensible.
A web application works with the database. Once a day, the database should be scanned and alerts should be sent to users.
From what I've seen out there, additional project has to be created which will be installed on the server and will work with the same database. Executable created by this project has to be installed in Windows scheduler to be activated once a day.
This seems complicated and inefficient: starting additional executable and working on the same database.
Is this the best possible way to do this?
Well you have different possibilities: Windows Scheduler with an executable is a good one. Another possibility is to write a Windows Service which will execute the task in the background. Quartz.NET is a good framework for this but the Windows Scheduler might be sufficient for your scenario. One thing is for sure: it is be better to perform these tasks outside of your ASP.NET application.
Usually I would look at writing a Windows Service to manage tasks that aren't suited to being hosted in a web application. These types of tasks are usually long running processes or scheduled tasks. Although this is normally the primary approach for these types of tasks, people have looked at ways of running these kinds of background processes in a web application by kicking off a number of threads in the Application_Start event exposed by Global.asax. The problem with this approach has always been that if your IIS worker process dies, then your background thread is killed too (effectively your 'Windows Service' is stopped until the next request is received).
ASP .NET 4.0 offers a solution to this problem. You can now set the StartMode to 'AlwaysRunning' as described in this blog post by Scott Gu. Somewhere in the comments on this post, someone asks a question about the viability of hosting Windows Service type tasks in IIS since the new feature ensures the worker process is always running. Scott mentioned that it would definitely support the scenario. Further to this, the recent introduction of AppFabric means that Microsoft themselves are providing simple hooks for hosting and monitoring WCF and WF services in a web application.
What does this mean for those of us that used to write Windows Services to support our web apps? Should we adopt this model? What are the pitfalls? As far as I can tell, there are a number of benefits to hosting 'Windows Service' processes in a web application, the most useful being the ease of deployment. Furthermore, we can actually start developing simple user interfaces to our services which provide information about what is happening at runtime.
If I had to go this route, I don't think that I would host my 'Windows Service' type functionality in the customer facing web application. I would probably develop a new web application project (much like I would in the Windows Service context) that would host my long running/scheduled task processes. I guess there are few reasons for this.
Security. There may be a different security model for the UI displaying information about the running background processes. I would not want to expose this UI to anyone else but the ops team. Also, the web application may run as a different user which has an elevated set of permissions.
Maintenance. It would be great to be able to deploy changes to the application hosting the background processes without impacting on user's using the front end website.
Performance. Having the application separated from the main site processing user requests means that background threads will not diminish IIS's capability to handle the incoming request queue. Furthermore, the application processing the background tasks could be deployed to a separate server if required.
I would be really interested to hear your thoughts on this approach and whether I should be sticking with Windows Services. I am very tempted to try this new approach.
What does this mean for those of us that used to write Windows Services to support our web apps?
I think this a key scenario where you could be move away from a Windows service to using the continous running web site.
Should we adopt this model?
Standard development answer: Depends ;)
What are the pitfalls?
One issue I can see is the IIS dependency. If you need a service to run on a users machine I would not feel comfortable about asking them to install IIS just to run my service. Here I think the traditional model works better.
Monitoring and tracking are major issues, but as you also point out this is solved by AppFabric. It is even better than what you get from the Window Service. However you have added another dependency which also will require .NET 4.0 and a relatively new version of Windows. I could also be wrong here, but my understanding is that AppFabric is not supported in production on client OS's. Which could bring in additional headaches.
You will lose pause functionality in the continuous web site model too.
Finally IIS killing inactive app-pools isn't the only way an app pool can recycle. Editing a web.config file causes it for instance, which may not be an ideal situation.
the most useful being the ease of deployment.
I also think development is much easier - in the past I have had a console app and a windows service so I can dev/test on my machine using the console app and then change it to a windows service when it goes out. Now dev/test is MUCH easier.
A must read for this is Death to Windows Services...Long Live AppFabric!
What are the pitfalls?
One I found, no shutdown event. You have AppStart when the web site starts (not global.asax because that is HTTP only) but you have no way to handle shutdown which could mean disposing becomes an issue.
I would suggest sticking with a windows service. The issue is with your number 2.
You won't be able to update service part of web site without restarting whole web site.
What are the advantages/disadvantages to running time based jobs using:
windows services
Application_BeginRequest to start seperate threads / timers.
One disadvantage of running the jobs in the context of a asp.net web appplication is during .net recycling things will have to be setup again, any others?
To my mind, there's no real benefit to doing time-based things in a web app. Go straight to a windows service. You know the process should be up and running all the time.
The ASP.NET site may simply unload, and will only operate again once someone starts browsing. The lifecycle is all wrong -- it's much 'choppier' than a service.
Lastly, services aren't very hard to create.
If you have administrative access to the server, I would either run a Windows Service or a scheduled SQL job depending on what you are trying to achieve.
It is nice to be able to stop/start and log these jobs independent of your web application. Also, if you have problems or errors in the job, it could adversely affect your website.
Finally, you are forcing the web application to go through code at every request to see if the timer has elapsed, which is an unnecessary overhead.
As I said to start with, the implementation depends on what the job is. If it is simply to update a number of database records, I'd use a scheduled job in SQL Server. If you need file I/O or access to external services, then a Windows Service might be more appropriate.
It is worth noting that you need to build in your own scheduling and thread safety into Windows Services. An alternative is to build a console application and use an application like FireDaemon for the scheduling.