Strange behavior of Windows Azure Compute Emulator (SDK 1.8) with multiple role instances on a clean machine with VS2012 but WITHOUT VS2010

StackOverflow https://stackoverflow.com/questions/13946634

  •  10-12-2021
  •  | 
  •  

Question

Have you ever tried to run a hosted service in the windows azure emulator with full IIS and multiple role instances? Some days ago I noticed that only one of the multiple instances of a web role is startet in IIS at a time. The following screenshot illustrates the behavior and the message box in front of the screenshot shows the reason for this behavior. The message box appears on trying to start one of the stopped websites in the IIS Manager.

Screenshot: IIS with stopped Websites

The sample cloud application contains two web roles: MvcWebRole1 and WCFServiceWebRole1 each configured to use three instances. My first thought was: "Sure! No port collision will happen in the real azure world because every role instance is an own virtual machine. It cannot work in the emulator!" But after some research and analyzing many parts of the azure compute emulator I found out that the compute emulator creates a unique IP for each role instance (in my example from 127.255.0.0 up to 127.255.0.5). This MSDN blog article (http://blogs.msdn.com/b/avkashchauhan/archive/2011/09/16/whats-new-in-windows-azure-sdk-1-5-each-instance-in-any-role-gets-its-own-ip-address-to-match-compute-emulator-close-the-cloud-environment.aspx) of the microsoft employee Avkash Chauhan describes this behavior as well. After that conclusion I came to the following question: why the hell does the compute emulator (more precisely DevFC.exe) not add the IP of the appropriate role to the binding information of each Website???

I added the IP to each Website by hand and tadaaaaa: every Website can be started without any collisions. The next screenshot demonstrates it with the changed binding information highlighted.

Screenshot: IIS with started Websites

Once again: Why the hell does the emulator not do it for me? I wrote a small static helper method to do the binding extension thing for me on every role start. Maybe someone wants to use it:

public static class Emulator
{
    public static void RepairBinding(string siteNameFromServiceModel, string endpointName)
    {
        // Use a mutex to mutually exclude the manipulation of the iis configuration.
        // Otherwise server.CommitChanges() will throw an exeption!
        using (var mutex = new System.Threading.Mutex(false, "AzureTools.Emulator.RepairBinding"))
        {
            mutex.WaitOne();

            using (var server = new Microsoft.Web.Administration.ServerManager())
            {
                var siteName = string.Format("{0}_{1}", Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.CurrentRoleInstance.Id, siteNameFromServiceModel);
                var site = server.Sites[siteName];

                // Add the IP of the role to the binding information of the website
                foreach (Binding binding in site.Bindings)
                {
                    //"*:82:"
                    if (binding.BindingInformation[0] == '*')
                    {
                        var instanceEndpoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints[endpointName];
                        string bindingInformation = instanceEndpoint.IPEndpoint.Address.ToString() + binding.BindingInformation.Substring(1);
                        binding.BindingInformation = bindingInformation;
                        server.CommitChanges();
                    }
                    else
                    {
                        throw new InvalidOperationException();
                    }
                }
            }

            // Start all websites of the role if all bindings of all websites of the role are prepared.
            using (var server = new Microsoft.Web.Administration.ServerManager())
            {
                var sitesOfRole = server.Sites.Where(site => site.Name.Contains(RoleEnvironment.CurrentRoleInstance.Role.Name));
                if (sitesOfRole.All(site => site.Bindings.All(binding => binding.BindingInformation[0] != '*')))
                {
                    foreach (Site site in sitesOfRole)
                    {
                        if (site.State == ObjectState.Stopped)
                        {
                            site.Start();
                        }
                    }
                }
            }

            mutex.ReleaseMutex();
        }
    }
}

I call the helper method as follows

public class WebRole : RoleEntryPoint
{
    public override bool OnStart()
    {
        if (RoleEnvironment.IsEmulated)
        {
            AzureTools.Emulator.RepairBinding("Web", "ServiceEndpoint");
        }

        return base.OnStart();
    }
}
Was it helpful?

Solution

I got it!

I have this behavior on three different machines which are all formatted and served with fresh clean windows 8, Visual Studio 2012 and Azure SDK 1.8 and Azure Tools installations recently. So a reinstallation of the Azure SDK and Tools (as Anton suggests) should not change anything. But the cleanliness of my three machines is the crucial point! Anton, do you have Visual Studio 2010 on your machine with at least VS2010 SP 1 installed? I analyzed IISConfigurator.exe with ILSpy and found the code which sets the IP in the binding information of the websites to '*' (instead of 127.255.0.*). It depends on the static property Microsoft.WindowsAzure.Common.Workarounds.BindToAllIpsWorkaroundEnabled. This method internally uses Microsoft.WindowsAzure.Common.Workarounds.TryGetVS2010SPVersion and leads to setting the IP binding to '*' if the SP level of Visual Studio 2010 is smaller than 1. TryGetVS2010SPVersion checks four registry keys and I don't know why but one of the keys exists in my registry und returns the Visual Studio 2010 SP level 0 (I never installed VS2010 on no one of the three machines!!!). As I changed the value of HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\DevDiv\vs\Servicing\10.0\SP from 0 to 10 (something greater 0 should do it) the Azure Emulator starts to set the 127.255.0.* IPs of the roles to the binding information on all of the websites in the IIS and all websites are started correctly.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top