1

I've been having an issue with my Entity Framework based website after hosting it on Microsoft Azure. If no calls have been made to the server within about 30 minutes, the server stops responding completely and returns Internal Server Errors (500) for all requests.

This was not an issue when I was running the site locally (I could leave it running for hours with nothing happening) and it would still work when I came back to it. I managed to fix the issue by running a loop that pings the server every 15 minutes, but that's obviously not a good solution; so my question is: where and how can I configure the connection properties for my server to prevent it from dying when not in use?

I know very little about connection authentication and I have no idea how to troubleshoot this when the only error I get is an Internal Server Error (which tells me nothing).

Here is the code on Github: https://github.com/synthc/UMD.git

synthc
  • 25
  • 5
  • 1
    I haven't faced this issue but it makes me wonder if a worker thread is being recycled after 30 minutes of inactivity. Are you preserving database contexts for a long time? – Basic Apr 10 '16 at 19:54
  • Well, I'm doing nothing to re-initialize my db context, so I would assume it never gets re-assigned (is that a bad thing?). – synthc Apr 10 '16 at 20:24
  • I don't have recent experience with Azure, so can't comment directly. In my MVC apps, the db context lives for the lifetime of the request. That allows me to do things like reverting changes without worrying about interfering with other requests. Have a look at using Unity to retrieve a DBContext. It can handle the lifetime of the objects for you. See http://stackoverflow.com/a/18264598/156755 – Basic Apr 10 '16 at 21:05
  • Much better writeup with decent explanation: http://stackoverflow.com/a/10588594/156755 – Basic Apr 10 '16 at 21:18
  • During the time it is working, how much traffic do you have. Do any other code blocks or systems do any work on the DB. We had something similar until we noticed that EF is fucking up the statistics. – user853710 Apr 11 '16 at 07:55

1 Answers1

1

A number of things came to mind that I would like to share with you - one of which already pointed out by Basic.

Always On

So first off - the reason why it may seem that your web app 'goes to sleep' is because of a feature in Azure Web Apps that can be turned off:

Always On description

You can read more about this feature here.

I suspect that something goes wrong while trying to get your web app back up, namely something with your database connection - which causes the 500s.

Datacontext lifetime management

So, indeed, as Basic pointed out - I would recommend using dependency injection ( DI ) for your Entity Framework ( EF ) context into your controller. This will give the EF datacontext the lifetime of a single request, which greatly reduces the context to enter a faulty state.

Ninject was the DI container that I used most often, and here's a write-up of how to get that to work with ASP.NET MVC: http://www.davepaquette.com/archive/2013/03/27/managing-entity-framework-dbcontext-lifetime-in-asp-net-mvc.aspx

Entity Framework execution strategy

Finally - EF offers different execution strategies for the database. And it offers a special one for connections on Azure. You wan to look into enabling the SqlAzureExecutionStrategy as described here: https://msdn.microsoft.com/en-us/data/dn456835.aspx . This will deal better with transient fault handling which might occur in the cloud.

I'm pretty sure that if you use all this - you should be fine and you 500s should be gone.

Jochen van Wylick
  • 5,303
  • 4
  • 42
  • 64
  • Thanks for the answer. Unfortunately my Azure subscription doesn't allow me to use Always On (I'm looking at upgrading now). As for dependency injection, I am already using Ninject to bind my custom repository to an interface and then I'm injecting that into my controller. This should be initializing the db context once per request since it's initialized inside my repository, right? – synthc Apr 11 '16 at 20:18
  • The DI container will be configured to apply a lifetime (aka scope) for the instances it creates. For NInject, see the [object scope documentation](https://github.com/ninject/ninject/wiki/Object-Scopes) and specifically [InRequestScope](https://github.com/ninject/Ninject.Web.Common/wiki/InRequestScope) – Basic Apr 12 '16 at 00:07