Ok, gonna squeeze out a quick blog post cause it’s been way to long between drinks. I have been coding like a mad man on a new project,hence the tumbleweeds on the social front.

So todays post is about creating a simple task for warming up your Azure Web Roles.

Why is this important? Well if there is a lull in traffic to your site IIS will nod off and all that cached data that makes your site responsive and snappy will be lost. You are caching your data right?

So there are various techniques out there and this simple one is based on a post of another tech blogger, extending it to allow pings to multiple pages.

Read on for all the geeky lovelyness.

Without further ado let’s dive head first in to the code:

publicclass WebRoleWarmUp { private Thread worker; publicvoid Start() { worker = new Thread(new ThreadStart(WarmUp)); worker.IsBackground = true; worker.Start(); } publicvoid WarmUp() { while (true) { try { using (EFEntities ctx = new EFEntities(Configuration.EntityConnection)) { var pages = (from p in ctx.WarmUpPages select p).ToList(); foreach (WarmUpPage item in pages) { var endpoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["HttpIn"]; var address = String.Format("{0}://{1}:{2}{3}", endpoint.Protocol, endpoint.IPEndpoint.Address, endpoint.IPEndpoint.Port, item.Page); var webClient = new WebClient(); webClient.DownloadString(address); System.Diagnostics.Trace.TraceInformation(string.Format("Pinged {0}",item.Page)); } } } catch (Exception e) { System.Diagnostics.Trace.TraceInformation(string.Format("Warm Up Error: {0}", e.Message)); Logging.LogError(e); } Thread.Sleep(60000); } }

So what does this simple wrapper class do. Well it spawns a new thread on Start and kicks off the WarmUp method.

That then goes in to an infinite loop and sleeps every 60 seconds.

Inside the loop we get a list of pages to hit from our WarmUpPages entity. This is just a basic table with a list of relative URL’s to hit that we want to prod and as a result trigger the code that will populate the local memory cache for the current Role Instance.

For now, to keep the solution a little cheaper, I am not using the Azure Distributed Cache (I would like to be though) but instead a custom caching solution that is safe across Role Instances with a (roughly) 5 second interval for differences in data. Due to the nature of the site and the volatility of the data this is an acceptable amount of difference.

Once we have all out pages we loop through them, create WebClient that points to the current Role Instance endpoint and then just ping the page by downloading it as text.

Ok so where do we start this from. Well from within the WebRole RoleEntryPoint of course. Code shown below:

publicclass WebRole : RoleEntryPoint { private WebRoleWarmUp warmUpTask; publicoverridebool OnStart() { warmUpTask = new WebRoleWarmUp(); warmUpTask.Start(); returnbase.OnStart(); } }

That’s it.A simple task for warming up your web site across x number of WebRoles. The current project I am working on relies on a lot of cached data and this solution has proved extremely effective in making the site very responsive.

Finally here are the gotchas. If like me you are using EntityFramework for data access you can’t rely on the connection being read from the Web.Config, you will need to pass the connection string to your context and read it from the Azure Configuration settings instead:

publicstaticstring EntityConnection { get { return RoleEnvironment.IsAvailable == true ? RoleEnvironment.GetConfigurationSettingValue("EntityConnection") : Properties.Settings.Default.EntityConnection; } }

It’s never going to read from the default properties (as shown above) but I have left that in to be consistent with all the other settings I am reading in my application for testing locally and outside of the Azure Compute Emulator.

Job done!

BondiGeek