Search code examples
c#asp.net-mvcasp.net-mvc-4async-awaitpolling

Stop action that takes a long time timing out load balancer


I'm trying to find a solution to a send email action that may take a long time and time out our load balancer which is on Rackspace. The only question I could find that relates to this specific issue is this:

keep load balancer from timing out during long operation

As I understand it I need to run another action whilst the main slow action is completing to constantly poll and return in order to keep things alive. My email action contains the following:

 var sendto = db.Users
                    .Where(b => b.Id == model.SentTo |
                    ((model.SelectedRoles.Any(s => b.Roles.Select(h => h.RoleId).Contains(s)))
                    && ((b.enrollment.Any(h => h.cohort.CourseID == model.CourseID) | model.CourseID == null))
                    && (b.OrgID == model.OrgID | model.OrgID == null))).ToList();

                    foreach (var address in sendto)
                    {
                        string Body = "message goes here";

                        EmailConfig.SendMessageViaMailGun(filestoattach, address.Email, null, email.Subject, Body);
                    }

So a list is created and then looped through with emails being sent to each person on the list. The Async method answer in the question above seems like it would do the trick but in the comments I can see this is considered a bad idea. It's also out of date in terms of how async works in the latest MVC version.

My question is what is the best way to keep this action from timing out the load balancer whilst it is completing?


Solution

  • This has nothing to do with async really, it is an infrastructure issue.

    There are two ways to perform long operations:

    1. The proper way: have a backend server and a process running there + communicate to this backend process via queuing (or database polling), then the client updates based on the progress (stored in some database) and update the UI on the web server. You also need to track the progress on the backend to continue on case of unexpected shutdown.

    2. The cheap way: Spin a different thread (or task) on the web server, and have it perform the operation, and poll from javascript the progress of this thread. This could however get shut down any minute (webserver recycle) and you lose the operation (if you are ok with this), then you need to pick up the operation and continue. A crude way would be to just wrap the whole thing you have with Task.Run, and return right away, then query the progress from Javascript, but as I said above this is prone to interruptions.