I would like to display results of long running tasks and still have responsive web site. I am calculating several results and each calculation takes from few seconds to more than 10 seconds. If I put everything in controller the site will be dead for 10 - 20 seconds and then results will be displayed in view.
Rather than this I would like to immediately display a view and start with calculations. After each calculation is finished, the site should be updated (or at least status should be updated and results can be displayed at the end). It would be great if all calculations could run in parallel.
How can I implement this? Is there a sample that is already available?
PS: I have seen several web sites where you search for results (for instance airplane tickets) where site is updating during the search. Maybe this is similar.
You can use asynchronous methods and controllers instead of the default synchronous ones. Assuming you're talking about asp.net mvc, you could start by looking here http://www.asp.net/mvc/tutorials/mvc-4/using-asynchronous-methods-in-aspnet-mvc-4 and here http://msdn.microsoft.com/en-us/vs11trainingcourse_aspnetmvc4_topic5.aspx
Hope that helps, lemme know if not.
Related
I've been hunting around my issue for a while, probably the best I've come up with is another Stack Overflow question: How should I perform a long-running task in ASP.NET 4?
I'm in a similar place in that I'm wanting to understand what my options are, but I don't feel I know enough specifically about MVC to come to a view. I'm using MVC 5 but with the 4.8 framework, plus I note that technologies such as SignalR have become available since this question was asked. I was wondering if any experienced MVC'ers could give me a view?
I too have a long running process. More specifically, the user is importing a file. The file is delimited so the import happens line by line. The file might be thousands of lines long. Each line will be parsed and imported in a fraction of a second but the whole operation might take several minutes.
I don't particularly need behaviour to be asynchronous, but because of the length of the entire process I want to regularly update the user on progress. I'm wondering what options I have?
I've got a vague recollection that I might have looked at this problem 20-odd years ago (Classic ASP), and solved it by regular flushes, sending a bit more of the page to the client every few seconds, but I'm trying also to use a _Layout page now, so I've sent the page back already. So I don't think I have that option, even assuming such a mechanism still exists. A bit more recently, but still a while ago, I might have used javascript to poll but everything I'm reading now seems to point me to newer technologies which I'm not sure I fully understand yet.
I'm just wondering how would you solve this problem?
I would not be performing any of the file parsing on the web server, especially if it's thousands of rows long. I would delegate this to a background service of sorts, whether that be a Lambda service in the cloud or a Windows service or a scheduled task. You could then call your SignalR hub from the background task (whatever that might be) to update the progress of the import.
I'm using Glimpse to debug some perfomance problems in my website, and it seems that the server/framework sits iddle for too long between method calls.
This picture shows 320 ms of server time;
This second picture reveals that 125.29 ms are used by ViewResult.ExecuteResult (I understand that as "rendering", which seems pretty slow to me, considering that my views are pre-compiled - more on that below);
But the really odd thing here is that more than 100 ms are pretty much wasted with iddle time, as you can verify in this picture.
Those little blocks representing server work sometimes account for 0 ms! But then there's a lapse of about 15 ms before the next block.
Is it really iddle time? Do you have any tips for where to look next, or how to optimize this?
Disclaimer: I've been looking into this for a week or so, and I have already found and applied those general performance recommendations, like:
Only one View Engine is active (RazorViewEngine);
Run in Release mode;
Specify full view paths, like "~/Views/Folder/ActionName.cshtml".
Besides that, Donut Caching is active, views are pre-compiled with Razor Generator, and I'm using Glimpse for diagnostics. Anyways, I've tried disabling these things to ensure that they were not the offenders, and I verified that they're actually improving the times.
Thanks in advance.
I have an MVC project, and I'm looking at speeding things up. One thing I'm scratching my head over is the BeginProcesRequest() which I have no control over. Using New Relic I found that this method is, on average consuming 90% of the time required for the transaction to complete.
The code in my controller is pretty simple. It has a look for an action session for the user and redirects to their dashboard if it finds one. there isn't any database calls on the actual page. The only written is:
if (Session["UserID"] != null)
// Perform actions
The BeginProcessRequest() method takes almost 4 seconds as you can see in the screenshot
This can't be something unique to my site? I'm using a small EC2 instance for the server, and although there are other applications running on the site the CPU and memory stay pretty much at 0 throughout the request.
EDIT - Reviewed the following post:
What happens in BeginProcessRequest()?
However as my application is idle when the most time consuming requests take place I can't see how it could be related to competing threads.
I think the issue was with IIS, as after I changed the property of idle time-out in the application pool to be one day it now seems to load much faster on initial start.
I also explicitly disabled the session state on my home controller, and ensured that SQL Server's auto close parameter was set to off.
I'm going to create a view counter for articles. I have some questions:
Should I ignore article's author
when he opens the article?
I don't want to update database each
time. I can store in a
Dictionary<int, int> (articleId, viewCount) how many times
each article was viewed. After 100
hits I can update the database.
I should only count the hit once per
hour for each user and article. (if
the user opens one article many
times during one hour the view count
should be incremented only once).
For each question I want to know your suggestions how to do it right.
I'm especially interested how to do #3. Should I store the time when the user opened the article in a cookie? Does it mean that I should create a new cookie for each page?
I think I know the answer - they are analyzing the IIS log as Ope suggested.
Hidden image src is set to
http://stackoverflow.com/posts/3590653/ivc/[Random code]
[Random code] is needed because many people may share the same IP (in a network, for example) and the code is used to distinguish users.
Sure - I think that is a good idea
and 3. are related: The issue is where would you actually store this dictionary and logic.
An ASP.NET application or session scope are of course the easiest choice, but there you really need to understand the logic of application pools. ASP.NET applications are recycled from time to time: when there is no action on the site for a certain period or in special situations - e.g. if the process starts to take too much memory the application is shut down and a new one is started in the next request. There are events for session and application shut-down, but at least some years ago they were not really reliable: In many special cases they did not always fire. Perhaps they are better now, but it is painful to test. And 1 hour is really a long time: Usually sessions are kept alive only like 20 minutes after last request.
A reliable way would be to have a separate Windows service (a lot of work to program) or always storing to database with double-view analyses (quite a lot of overhead for such a small feature).
Do you have access to IIS logs? How about analyzing IIS logs e.g. every 30 minutes with some kind of timer process and taking the count from there? Or then just store all the hits to the database with user information and calculate the unique hits with a similar timed process.
One final question: Are you really sure none of the thousands of counter applications/services in the Internet wouldn't do the job close enough to your requirements?
Good luck!
This is the screenshot of this page in Firebug. You can see that there is a request which returns 204 status code (No Content).
This is stackoverflow's view counter. They are using a hidden image which point to a controller's action.
I have many articles. How to track which articles the user visited already?
P.S. BTW, why is this request made two times?
Like with browser games. User constructs building, and a timer is set for a specific date/time to finish the construction and spawn the building.
I imagined having something like a deamon, but how would that work? To me it seems that spinning + polling is not the way to go. I looked at async_observer, but is that a good fit for something like this?
If you only need the event to be visible to the owning player, then the model can report its updated status on demand and we're done, move along, there's nothing to see here.
If, on the other hand, it needs to be visible to anyone from the time of its scheduled creation, then the problem is a little more interesting.
I'd say you need two things. A queue into which you can put timed events (a database table would do nicely) and a background process, either running continuously or restarted frequently, that pulls events scheduled to occur since the last execution (or those that are imminent, I suppose) and actions them.
Looking at the list of options on the Rails wiki, it appears that there is no One True Solution yet. Let's hope that one of them fits the bill.
I just did exactly this thing for a PBBG I'm working on (Big Villain, you can see the work in progress at MadGamesLab.com). Anyway, I went with a commands table where user commands each generated exactly one entry and an events table with one or more entries per command (linking back to the command). A secondary daemon run using script/runner to get it started polls the event table periodically and runs events whose time has passed.
So far it seems to work quite well, unless I see some problem when I throw large number of users at it, I'm not planning to change it.
To a certian extent it depends on how much logic is on your front end, and how much is in your model. If you know how much time will elapse before something happens you can keep most of the logic on the front end.
I would use your model to determin the state of things, and on a paticular request you can check to see if it is built or not. I don't see why you would need a background worker for this.
I would use AJAX to start a timer (see Periodical Executor) for updating your UI. On the model side, just keep track of the created_at column for your building and only allow it to be used if its construction time has elapsed. That way you don't have to take a trip to your db every few seconds to see if your building is done.