Try fast search NHibernate

06 August 2011

Azure storage initialization

This is the “self response” to the previous post.

When your role starts on Azure there are some tasks which runs synchronously and some tasks which runs asynchronously. For complex startups you can set the configuration of each custom tasks in your ServiceDefinition.csdef. If you don’t need special tasks to setup your VM you will end initializing your Azure-storage (blob containers, tables and queues) somewhere. Our problem was exactly: WHERE?

If you have a WebRole you have two places where you can initialize the storage:

  • the WebRole
  • the Application_Start of the HttpApplication (Global.asax.cs)

Which is the right one ? are they ambivalent ? If you read the documentation there is something that is clear to me :

The Application_Start method is called after the RoleEntryPoint.OnStart method finishes. The Application_End method is called before the RoleEntryPoint.OnStop method is called.

From the doc the right place is the OnStart.

If you use the  AppSetting to store your account information (as we do to switch between production and test account) you have something like this (or an equivalent):

 

public static class AzureAccount
{
    private static string dataconnectionstring = "AzureDataConnectionString";

    static AzureAccount()
    {
        CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>
        {
            string value = ConfigurationManager.AppSettings[configName];
            if (RoleEnvironment.IsAvailable)
            {
                value = RoleEnvironment.GetConfigurationSettingValue(configName);
            }
            
            configSetter(value);
        });
    }

    public static CloudStorageAccount DefaultAccount()
    {
        return CloudStorageAccount.FromConfigurationSetting(dataconnectionstring);
    }
}

and the WebRole overriding the OnStart should be safe:

public class WebRole : RoleEntryPoint
{
    public override bool OnStart()
    {
        InitializeAzureStorage();

        return base.OnStart();
    }

and the initialization with something like this:

CloudStorageAccount account = AzureAccount.DefaultAccount();

// initialize the storage using the account

but it does not work always and if you look around the NET you will see various posts using Thread.Sleep here and there. The fact is that if you are using just the Web.Config, to store the AppSetting needed by the storage initialization, you don’t know exactly when it will be available ergo those Thread.Sleep may work sometimes but not always. To be sure that the AppSetting will be the correct, and overall you actually have the AzureDataConnectionString, you have to modify both ServiceDefinition.csdef and ServiceConfiguration.cscfg in this way:

ServiceDefinition

ServiceConfiguration

Note: you don’t have to remove the AzureDataConnectionString from your web.config… it is still useful to run the application as a web-application.

No comments:

Post a Comment