2
votes

I have a Worker Role that executes code (fetching data and storing it to Azure SQL) every X hours. The timing is implemented using a Thread.Sleep in the while(true) loop in the Run method.

In the Web Role I want to have the abillity to manualy start the code in Worker Role (manualy fecth and store data in my case). I found out that the whole Worker Role can be restarted using the Azure Management API but it seems like an overkill, especialy looking at all the work needed around certificates.

Is there a better way to restart Worker Role from Web Role or have the code in Worker Role run on demand from the Web Role?

2
Anything like posting an event to an Azure Queue, posting a blob to Azure Blobs, changing a record in Azure Tables or even making some change in SQL Azure will work - the web role will do the change and the worker role will wait for that change.sharptooth
@sharptooth make your comment an answer and I will accept it. It is easy and I think will be sufficient.Igor Kulman

2 Answers

1
votes

Well I suggest you use Azure Fluent Management (which uses the Service Management API internally). Take a look at the "Deploying to Windows Azure" page.

What you will want to do is the following:

  • Cloud Service: mywebapp.cloudapp.net
    • Production slot
      • Role: MyMvcApplication
  • Cloud Service: mybackgroundworker.cloudapp.net
    • Production slot
      • No DEPLOYMENT

So you would typically have a Cloud Service running with a Web Role and that's it. What you do next is create the Worker Role, add your code, package it to a cspkg file and upload it to blob storage.

Finally you would have some code in your Web Role that can deploy (or remove) the Worker Role to that other Cloud Service by downloading the package locally and then running code similar to this:

 var subscriptionManager = new SubscriptionManager(TestConstants.SubscriptionId);
 var deploymentManager = subscriptionManager.GetDeploymentManager();

 deploymentManager
       .AddCertificateFromStore(Constants.Thumbprint)
       .ForNewDeployment(TestConstants.HostedServiceName)
       .SetCspkgEndpoint(@"C:\mypackage")
       .WithNewHostedService("myelastatestservice")
       .WithStorageAccount("account")
       .AddDescription("my new service")
       .AddLocation(LocationConstants.NorthEurope)
       .GoHostedServiceDeployment();
1
votes

Anything like posting an event to an Azure Queue, posting a blob to Azure Blobs, changing a record in Azure Tables or even making some change in SQL Azure will work - the web role will do the change and the worker role will wait for that change. Perhaps Azure Queues would be the cleanest way, although I'm not sure.

One very important thing you should watch for is that if you decide to use polling - like query a blob until it appears - you should insert a delay between the queries, otherwise this code:

while( true ) {
   if( storage.BlobExists( blobName ) ) {
       break;
   }
}

will rush into the storage and you'll encounter outrageous transaction fees. In case of SQL Azure you will not see any fees, but you'll waste the service capacity for no good and this will slow down other operations you queue to SQL Azure.

This is how is should be done:

while( true ) {
   if( storage.BlobExists( blobName ) ) {
       break;
   }
   // value should not be less that several hundred (milliseconds)
   System.Threading.Thread.Sleep( 15 * 1000 );
}