There are two classes which allow us to hook into the events in case of role state/status change; events in the RoleEntryPoint
class and events in the RoleEnvironment
class. Two of these events, OnStart
and OnStop
, are present in the RoleEntryPoint
class (as seen in my previous post) which you can override in your main WebRole
or WorkerRole
class. The other three; Changing
, Changed
, Stopping
, SimultaneousChanging
and SimultaneousChanged
, are the events present in the RoleEnvironment
class. In this post, I will walk you through each one of them.
OnStart()
The chain of events start with OnStart()
. When the WebRole
or WorkerRole
instance is started, the Azure agent will search through the roles primary assembly, for a class that inherits the RoleEntryPoint
class. The OnStart()
method of this class is then called. The method looks like this:
public override bool OnStart()
{
ServicePointManager.DefaultConnectionLimit = 12;
return base.OnStart();
}
OnStart()
allows us to run any initialization tasks, before starting a role instance. While running any initialization tasks, the status of the role instance is set to busy. When a role instance is busy, no traffic is sent to it by the load balancer. The method returns a boolean value indicating whether the task completed successfully or not. If the OnStart()
method returns false
, the role instance is immediately stopped. Otherwise, Windows Azure sets the roles status as ready and starts executing the role by calling the Run()
method. There are a couple of other places where we can also run the initialization task:
- In a web role, we can also include initialization code in the ASP.NET
Application_Start()
method instead of the OnStart()
method. The Application_Start()
method is called after the OnStart()
method. - In the roles service definition file, we can specify a startup task also. That can execute as a separate process and can be run at a different privilege level other than the main entrypoint.
Although there are differences in running initialization tasks using OnStart()
method and roles service definition file and can be found over here.
OnStop()
OnStop()
method provides us 5 minutes to clean up and persist any state. If we are unable to finish our clean up within 5 minutes, then, it will terminate and we will lose anything we wanted to do.
public override void OnStop()
{
try
{
}
catch (Exception e)
{
Trace.WriteLine("Exception during OnStop: " + e.ToString());
}
}
The OnStop()
method gets called in case of these events:
- When the user knowingly stops a role
- When the instance responsible for running a role, is recycled by Azure run time, or in case of an OS upgrade
- When we are scaling down, i.e., decreasing the number of instances
RoleEnvironment.Stopping
The Stopping
event is used to run code when a role instance is being stopped, but before the OnStop
method is called. Once the Stopping
event is raised, the load balancer stops sending requests.
public override bool OnStart()
{
RoleEnvironment.Stopping += RoleEnvironmentStopping;
return base.OnStart();
}
private void RoleEnvironmentStopping(object sender, RoleEnvironmentStoppingEventArgs e)
{
}
One thing to remember is, the Stopping
event does not get raised when the virtual machine of the role instance is rebooted.
RoleEnvironment.Changing
Changing event occurs before a change to the service configuration is applied to the running instances of a role. Both RoleEnvironment
’s Changing
and Changed
event are used together to identify and manage configuration changes to the service model. By using the Changing
event, an instance can respond to a configuration change in one of the following ways:
- Accept the configuration change while it is running, without going offline.
- Set the
Cancel
property of RoleEnvironmentChangingEventArgs
to true
to take the instance offline, apply the configuration change, and then bring the instance back online.
By using the Cancel
property, we can gracefully stop each role instance before taking it offline and applying the new configuration changes. During the shutdown process, Windows Azure raises the Stopping
event, and then runs any code in the OnStop
method.
public override bool OnStart()
{
RoleEnvironment.Changing += RoleEnvironmentChanging;
return base.OnStart();
}
private void RoleEnvironmentChanging(object sender, RoleEnvironmentChangingEventArgs e)
{
if ((e.Changes.Any(change => change is RoleEnvironmentConfigurationSettingChange)))
{
e.Cancel = true;
}
}
We can choose whether the instance should be recycled to deal with the configuration change or not by setting e.Cancel
to true
/ false
. Setting Cancel
to true
indicates the role should be recycled. The callback method for the Changing
event has access to the old value of the configuration setting and can be used to control whether or not the instance is restarted in response to the configuration change.
RoleEnvironment.Changed
The Changed
event occurs after a change to the service configuration is applied to the running instances of a role. We can use the Changing
event to decide when the changes are applied.
public override bool OnStart()
{
RoleEnvironment.Changed += RoleEnvironmentChanged;
return base.OnStart();
}
private void RoleEnvironmentChanged(object sender, RoleEnvironmentChangedEventArgs e)
{
var settingChanges = e.Changes.OfType<RoleEnvironmentConfigurationSettingChange>();
foreach (var settingChange in settingChanges)
{
Trace.WriteLine("Setting: " + settingChange.ConfigurationSettingName, "Information");
}
}
The callback method for the Changed
event has access to the new value of the configuration setting and can be used to reconfigure the instance in response to the change. The RoleEnvironmentChangedEventArgs
object provides the settings that were changed in the service configuration.
RoleEnvironment.SimultaneousChanging & RoleEnvironment.SimultaneousChanged
SimultaneousChanging
and SimultaneousChanged
events are the same as that of the Changing
and Changed
event, except that it occurs when the service configuration is to be applied to all running instances of a role at the same time.
public override bool OnStart()
{
RoleEnvironment.SimultaneousChanging +=
RoleEnvironmentSimultaneousChanging;
RoleEnvironment.SimultaneousChanged +=
RoleEnvironmentSimultaneousChanged;
return base.OnStart();
}
private void RoleEnvironmentSimultaneousChanging(object sender,
SimultaneousChangingEventArgs e)
{
var topologyChanges = e.Changes.OfType<SimultaneousTopologyChange>();
foreach (var change in topologyChanges)
{
if (change.RoleName.Equals(
RoleEnvironment.CurrentRoleInstance.RoleName))
{
}
}
}
private void RoleEnvironmentSimultaneousChanged(object sender,
SimultaneousChangedEventArgs e)
{
var topologyChanges =
e.Changes.OfType<SimultaneousTopologyChange>();
foreach (var change in topologyChanges)
{
var message = "Topology change: " + change.RoleName;
Trace.WriteLine(message, "Information");
}
}
Tom Hollander’s post further explains when and how the above events occur and is worth going through.
The post Understanding azure role topology changes appeared first on Its me !.
CodeProject