2

I have a website on Rackspace which does calculation, the calculation can take anywhere from 30 seconds to several minutes. Originally I implemented this with SignalR but had to yank it due to excessive CC usage. Hosted Rackspace sites are really not designed for that kind of use. The Bill went though the roof.

The basic code is as below which work perfectly on my test server but of course gets a timeout error on Rackspace if the calculation take more than 30 seconds due to their watcher killing it. (old code) I have been told that the operation must write to the stream to keep it alive. In the days of old I would have started a thread and polled the site until the thread was done. If there is a better way I would prefer to take it.

It seems that with .NET 4.5 I can use the HttpTaskAsyncHandler to accomplish this. But I'm not getting it. The (new code) below is as I understand the handler you would use by taking the old code in the using and placing it in the ProcessRequestAsync task. When I attempt to call the CalcHandler / Calc I get a 404 error which most likely has to do with routing. I was trying to follow this link but could not get it to work either. The add name is "myHandler" but the example link is "feed", how did we get from one to the other. They mentioned they created a class library but can the code be in the same project as the current code, how?

http://codewala.net/2012/04/30/asynchronous-httphandlers-with-asp-net-4-5/

As a side note, will the HttpTaskAsyncHandler allow me to keep the request alive until it is completed if it takes several minutes? Basically should I use something else for what I am trying to accomplish.

Old code

[Authorize]
[AsyncTimeout(5000)] // does not do anything on RackSpace
public async Task<JsonResult> Calculate(DataModel data)
{
   try
   {
        using (var db = new ApplicationDbContext())
        {
           var result = await CalcualteResult(data);
           return Json(result, JsonRequestBehavior.AllowGet);
        }
   }
   catch (Exception ex)
   {
      LcDataLink.ProcessError(ex);
   }

   return Json(null, JsonRequestBehavior.AllowGet);
}

new code

public class CalcHandler : HttpTaskAsyncHandler
{
    public override System.Threading.Tasks.Task ProcessRequestAsync(HttpContext context)
    {
        Console.WriteLine("test");
        return new Task(() => System.Threading.Thread.Sleep(5000));
    }
  }
John Hughes
  • 367
  • 1
  • 3
  • 20
  • Seems to me the most direct solution is to remove/raise the RackSpace request timeout limitation. On a side note, `AsyncTimeout` must be used in conjunction with a `CancellationToken` - it won't kill your request like a synchronous timeout will; it will only ask it to cancel by setting the `CancellationToken`. – Stephen Cleary Mar 01 '15 at 13:15
  • I agree about Rackspace increasing the timeout but it is not an option. Do you happen have a reference or example for using the CancellationToken with MVC 5 & .NET 4.5? – John Hughes Mar 01 '15 at 20:59
  • http://www.asp.net/mvc/overview/performance/using-asynchronous-methods-in-aspnet-mvc-4#CancelToken – Stephen Cleary Mar 02 '15 at 02:09

1 Answers1

0

It's not a best approach. Usually you need to create a separate process ("worker role" in Azure).

This process will handle long-time operations and save result to the database. With SignalR (or by calling api method every 20 seconds) you will update the status of this operation on client side (your browser).

If this process takes too much time to calculate, your server will become potentially vulnerable to DDoS attacks.

Moreover, it depends on configuration, but long-running operations could be killed by the server itself. By default, if I'm not mistaken, after 30 minutes of execution.

Roman Pushkin
  • 5,639
  • 3
  • 40
  • 58
  • 1
    Sorry but I don't understand how this applies to my question. They are requests that take up to a couple minutes not long running operations. Does .NET 4.5 have a better method of implementing these API request or just revert back to the old standard? Was I that unclear in my question? – John Hughes Mar 01 '15 at 12:40