0

Building off of this question/answer on StackOverflow, I'm looking to make a single Azure instance run certain code at one time rather than have every instance run the code.

However, what I can't seem to find is how to determine if roles that are still in RoleEnvironment.CurrentRoleInstance.Role.Instances are busy and/or healing. I would need this to hand over control over running my code to another instance if one is failing.

RoleInstance doesn't seem to have any properties to determine current role status.

Community
  • 1
  • 1
David Pfeffer
  • 38,869
  • 30
  • 127
  • 202

2 Answers2

1

Might I suggest a different take, rather then use a complex topology based selection, instead implement a simple 'traffic cop' pattern. In a nutshell, this uses a temporary blob lease to ensure that only one instance (the one that gets the lock) can perform the singleton operation. If the instance that was doing the action becomes unresponsive, the lease will fail to be renewed and another instance can quickly take over processing.

I have some sample code and a write-up on my blog at: http://brentdacodemonkey.wordpress.com/2012/07/27/the-traffic-cop-pattern/

BrentDaCodeMonkey
  • 5,493
  • 20
  • 18
  • smarx actually has a library available to do this. However, my concern is what happens when Azure Storage fails, as has happened in the past. – David Pfeffer Aug 22 '13 at 13:49
  • There are already multiple dependencies on Storage already, so what's one extra. Worst case, with this pattern, the action simply won't be performed as none of the instances can establish a lease. – BrentDaCodeMonkey Aug 22 '13 at 14:18
  • I don't have any dependencies on storage in my application. – David Pfeffer Aug 22 '13 at 14:27
  • 1
    You may not direct, but there are interdependencies between various Windows Azure Services. With PaaS, your diagnostic information is persisted to storage, plus your deployments are dependent on storage as well (the cspkg's are placed there). So if there was a storage outage (there's only been one global outage and that affected HTTPS traffic only), you would likely lose the ability to deploy new cloud service updates, and there's a risk that if a fabric upgrade was on-going, new instances may not start properly (aka the topology changes you are taking a dependency on). – BrentDaCodeMonkey Aug 22 '13 at 14:30
  • Fair enough. I'm still interested in the direct answer to my question, but I will probably end up implementing your methodology for my software. – David Pfeffer Aug 22 '13 at 15:32
  • I believe you can get the state from the Management API. http://msdn.microsoft.com/en-us/library/windowsazure/ee460806.aspx If you set "imbedded-detail" to true, you'll notice you get back the status of all instances in the service. If its JUST the current instance you're concerned about, you can track your own status based on the other events that are present in the RoleEntryPoint. You'll be issues events you can trap/respond to for things like "Stopping" "Starting", and you control the "busy" response via RoleEnvironmentStatusCheck event. – BrentDaCodeMonkey Aug 22 '13 at 16:23
  • I've actually tried the blob lock strategy before, but I also always hit into this issue: http://stackoverflow.com/questions/8057951/azure-blob-lease-doesnt-release-upon-ungraceful-exit – David Pfeffer Aug 22 '13 at 16:50
0

Have you tried a service bus based approach? push the task to be completed into a topic. The instance can create a subscription named based of the instance number. (which you can get out of the RoleEnvironment.CurrentInstance.Id). In this way, even if the instance goes down, the message will still be delivered to the subscription for the instance to grab after it comes back up.

The subscriptions could also be filtered subscriptions based on data on the message.

Either way a simple queueing mechanism might line up more semantically with what you are trying to do.

Dennis Burton
  • 3,282
  • 3
  • 23
  • 30