Background task / job / process, in asp.net MVC 3 - asp.net-mvc

I don't know where to start or what to use to solve this 2 problems:
I have a User model and a Event model (football match, karts race, etc). And I want that when a user creates a new Event send and email to other users.
I need "something" that checks let's say every 15 minutes, delete all the Events that are already over (Example: Events from yesterday) from the database.
I know that in Ruby on Rails, there are Observers and Background Workers, there is something like that in MVC3 ? or there are other ways of accomplish that ?

Those kind of tasks are better suited to be done from a separate process such as a Windows service. You should avoid using background tasks in your web applications.

I would suggest using Quartz.net as a robust solution because of being full-featured, open source job scheduling system that can be used from smallest apps to large scale enterprise systems.
More Info: Job Scheduler with asp.net mvc

It's true that there are risks. But sometimes we have to take this option, especially when we are on a tight schedule to implement a job queue. If you are not familier with windows services, you need to learn about those things.
Following worked for me, (.NET 4.5.2). Once I invoke InitiateLongRunningProcess controller, it initiate a longrunning process and return to view without waiting for the longrunning job.
public ActionResult InitiateLongRunningProcess(Emails emails)
{
if (ModelState.IsValid)
{
HostingEnvironment.QueueBackgroundWorkItem(ct => LongRunningProcessAsync(emails.Email));
return RedirectToAction("Index", "Home");
}
return View(user);
}
Read this great article from Hanselman HowToRunBackgroundTasksInASPNET

Pretty late but you should consider lookint at http://hangfire.io/. Its an amazing library and provides a full fletched UI to manage jobs :)

Related

How to implement a Quartz.NET job in ASP.NET MVC with UnitOfWorkPattern on EF Code first

I have ASP.NET MVC 3.0 application, with EF Code First for data layer. I have implemented a Unit of work pattern, I’m binding context of the unit of work on HttpContext.Current.Items[SomeKey] collection. Unit of work is created and committed in OnActionExecuting/Executed events on controller. I’m instantiating repositories using Windsor Castle.
Now I need to use Quartz.net to run a job periodically in my app, this job need also use few repositories. The problem is, that in a SchedulerJob implementation, there is no HttpContext available (indeed). How can I instantiate a repository (which takes UnitOfWorkFactory as constructor parameter) from a Quartz.net Job in that case? How can I substitute missing HttpContext? I will probably need to implement another UnitOfWorkFactory, but I’m not sure where I can bind my context and how to register different factory just for Quartz.net thread. Can you please show me a way or pattern? Thank you.
You might want to consider writing your own job factory and injecting your repositories there. I wrote a post on how to do this here. Windsor also has a facitlity for integrating Quartz.net directly.
One last comment... you shouldn't host Quartz.Net in your web app if you are going to schedule long running jobs or if you are going to schedule jobs to run periodically. IIS process recycling will not let your scheduler run properly. A windows service is the way to go.
The unit of work implementation belongs to the business logic layer and should not depend on a specific presentation layer such as MVC.
I made a custom UnitOfWorkScope that I've used in a couple of projects: http://coding.abel.nu/2012/10/make-the-dbcontext-ambient-with-unitofworkscope/

ASP MVC 3: run cron jobs without affecting the user

For my site I need to have:
logging of the action & render time
log the visit of a certain product
from time to time agregate votes
from time to time send newsletter
from time to time post on social networks
My approach to this was to create a global filter and OnResultExecuted I do the check and the action that are needed.
I have some questions:
when OnResultExecuted is running did the user received the rendered page and basically is not waiting for anything else? Am I blocking it?
it is a good idea in OnResultExecuted to start a new thread for this
jobs?
is this approach ok in ASP MVC 4
According to MSDN this method is called after the response is written (http://msdn.microsoft.com/en-us/library/system.web.mvc.controller.onresultexecuted(v=vs.108).aspx) so you will not be blocking the response.
Apart from the first two points (logging of actions and logging of visits), the others may take considerable resources based on the size of the task.
My advice is to override OnResultExecuted for the first two tasks and use a windows service (can easily be written in C#) to do the others in the background. This way you can use less costly clr threads instead of iis worker threads.
Running the time/resource consuming tasks in the background will add scalability to your web application
Hope this helps

Logging large volumes of actions in a production MVC/SQL application

We are happy users of the ASP.NET MVC framework and SQL Server, currently using LINQ-to-SQL. It serves our needs well with a consumer-facing application with about 1.4 million users and 2+ million active uniques per month.
We are long overdue to start logging all user actions (views of articles, searches on our site, etc.) and we're trying to scope out the right architecture to do so.
We'd like the archiving system to be its own entity, and not part of the main SQL cluster that stores the production articles and search engine. We'd like it to be its own SQL cluster, starting out with just one box initially.
To simplify the problem, let's say we just want to log the search terms that these millions of users enter into our site for the month, and we want to do so in the least cycle-intensive-way possible.
My questions:
(1) Is there an asynchronous way to dump the search terms to a remote box? Does LINQ support async for this?
(2) Would you recommend building up a cache of say 1,000 (userId, searchTerm, date) logging items in a RAM cache, and then flushing those at intervals to the database? I assume this method would cut down on open/close connections.
Or am I thinking about this entirely wrong? We'd like to strike a balance between ease of implementation and robustness.
1)Sure you can, there are different solution to achieve it. Linq is not the instrument you need.
2)There should not be any major improvement by doing it, the "logging" will be triggered only when a search is performed. You will end up with two calls instead of one, not a big deal.
A suggestion is to use AOP
You can create a clean and separate layer for logging using Postsharp (there are other alternatives though). You will then decorate your actions with the required logging attribute only when you need to trace what is passed to the action.
Main advantages with this approch are :
Logging logic doesn't reside inside your code (you don't need to change your methods code) but is executed before/after your method.
Clean separation of the Aspect from the target method.
You can easily switch on/off the aspects
AOP is a common practice specially when it comes to behavior that can be added to more than one method, like logging, authentication and so on. And yes it can be used in an async way.
1)I would suggest you to create an HttpModule that "catch" all the search terms used by the users. How and where you will dump those information(you said you will use a SQL box) it's another matter which is outside the scope of the module which should just catch the Search tems.
Then you can create a component that contains the login to store those information using Async call(or even a third part component like Log4Net )
2) if you want create a kind of batch insert caching all the information you need to store and at some point dump them on SQL I would use MSMQ or any other technology that support the Reliability: I think you want loose all those information in the case of a system-crash,etc

ASP.NET MVC Repeating Task

I need to run a task repeatedly on an ASP.NET MVC site; it needs to run every time interval (Interval doesn't matter).
I achieved this by setting a background thread from the Global.asax.cs Application_Start which runs the task, sleeps for time interval and then runs again....and again.
While this works it doesn't seem like the right way to do this, seems a bit hacky.
So then I replaced it with a Timer object, this doesn't work reliably - seems others have had problems with it as well - so I'm not going to use this.
This needs to run in the MVC site, it is used for pulling jobs from a queue and rendering them from the Views ready for emailing.
I thought about using the ThreadPool and getting the previous job to leave another job on it's way out but because these can be long running jobs I've read that this can end up not leaving enough threads to deal with web requests through starvation.
Before sticking with the original thread method I thought I'd ask if anyone else knows a better way of doing this.
I hope this makes sense. Effectively what I'm trying to achieve is a heartbeat. Something to act as the consumer part of the producer/consumer pattern in an MVC site.
Stackoverflow itself uses (or at least used to use) a cunning way of doing this. See here: https://blog.stackoverflow.com/2008/07/easy-background-tasks-in-aspnet/
In brief, you do this:
At startup, add an item to the HttpRuntime.Cache with a fixed
expiration.
When cache item expires, do your work, such as WebRequest or what have
you.
Re-add the item to the cache with a fixed expiration.
I know you've stated that:
This needs to run in the MVC site
However I think this is the wrong place for doing what you're trying to acheive.
Personally I'd set this up as a Windows Service and have the service check the database, compile the email as required, and add the email to a queueing service. The email service would then be seperate from this and would dispatch the emails at some interval.
What's stopping you at present from using another method than embedding this in your MVC site?

Which way to go - MVC REST or WCF REST?

I have a set of web methods that I am planning to convert to REST on top of MVC or WCF.
But I am little confused after reading few questions and answer on similar topic.
** My app is .NET 4, C# with Mongo database as backend which emits JSON **
Here is my use cases:
Persisting web form data (new user signs up, I need to save web form) &
show update status (success or failure)
User posts a new comment/reply. I need to save the comment in DB (async w/ jquery) &
show update status (success or failure)
User likes comment/reply. I need to save the like in DB (async w/ jquery) &
show update status (success or failure)
User updates title, tag or any other field. I need to update DB (async w/ jquery)
& show the update status to the user
User wants to view the next page of comments. I call web service and silently append
the comments.
In future I paln to open the API to other apps to talk to my app. So I need REST api to
handle that.
I am new to both MVC and WCF framework. So I need to learn either way I go.
But I would prefer easy and clean coding
Looking for light weight & faster solution (cheaper in the long run)
Please let me know if I have to specify anything else that might clarify my need.
Thanks
I would say it depends on your timeframe. If you need to put something into production within the next 3-6 months and your API is not going to be too large, and will stick to HTML/JSON then MVC will probably do you fine.
If this is a long term strategic project then I would keep an eye on http://wcf.codeplex.com. There is some excellent new stuff coming out of the WCF group for building sophisticated web apis.
Since you are writing a web application - I would go with MVC. You then get the testability benefits of MVC along with its inherent RESTfulness.
Tasks such as:
"Persisting web form data (new user signs up, I need to save web form) & show update status (success or failure)"
sure you can have a web app call a service to do this - but when you can get the web app and the call to do this all in a RESTful interface all inside of MVC - why go elsewhere? Rememeber - this stack overflow application is written in MVC : )
I would go with WCF, it is design for that purpose and if not all, most of the plumbing is done for you. With MVC to be used as restful service you will have re-implement few things to make it work like a real service.

Resources