Thursday, May 15, 2014

Grains and Reminders

The previous blog posts were about Orleans and Grains and how to build up a nice universe of grains. This post will demonstrate how to use reminders.

Reminders are almost equal to timer but there are a few differences:
- reminders will always trigger even when a grain is not implicitly activated.
- a grain gets reactivated when the reminder is fired.
- reminders should not be used for intensive timing purposed (don't fire one every second).

Reminders are a great fit for 'housekeeping' purposes. In my scenario, where devices are represented virtually by a grain and keeping state and history of the device, reminders will be used to periodically check if the device out there is still provisioned and part of the IoT game. Consider when I remove service identities on ACS. After removal devices are not able to send their temperatures to the event topic anymore and are not able to receive any commands in their subscription anymore. This probably means that the device is turned off, removed, stolen or any other reasons to remove the device from the universe. Using a reminder in this scenario can be helpful!

The reminder will perform the following tasks:
- fire every 10 minutes
- check on ACS if the associated service identity is still there
- if the service identity is missing, the reminder will set the device grain in a "inactive" state and remove it from the universe grain devices list and move it to the universe grain's "inactive devices"
- the reminder will also remove any other ACS related adminstration (rule groups, relying party)

Implementing this completely rules out the Device grain and puts the device in a blocked or inactive state (removing a grain is not possible in Orleans since you can activate or deactivate a grain). The block/inactive device grain will appear on the client as a red pushpin indicating it's deactivated state. Obviously, there are no updates send by the real device anymore since it's removed/stolen are turned off.

Reminders are persisted (they need to be since they also get trigger on deactivated grains!).

To make sure your reminders are persistent you need to add the following line to your OrleansConfiguration.xml settings.

ReminderServiceType="AzureTable"/>

To enable reminders on your grain you need to implement the IRemindable interface.


public class DeviceGrain : Orleans.GrainBase, IDeviceGrain, IRemindable

Implementation of the reminder which is started right away and gets fired every 10 minutes. In the RegisterDevice() method of the Device Grain we also register the reminder.

private IOrleansReminder reminder;

async Task IDeviceGrain.RegisterDevice()
{
   reminder = await RegisterOrUpdateReminder("Housekeeping", TimeSpan.FromMinutes(0), TimeSpan.FromMinutes(10));

   var universe = UniverseGrainFactory.GetGrain(0);
   await universe.RegisterDevice(this);
   }
}

public Task ReceiveReminder(string reminderName, TickStatus status)
{
   Trace.WriteLine("Housekeeping reminder is triggered");
   return TaskDone.Done;
}

Explicit deregistration of the device grain by user or system action deregisters the reminder we created before. This prevents the continuation of reminder being triggered.


public async Task UnregisterDevice()
{
   //make sure the reminder goes away since they are persistent! Explicit remove the reminder
   await UnregisterReminder(reminder);
}

Every time the reminder is triggered, I check my ACS assets to see if the device (it's service identity) was removed. Using reminders are a great way to do housekeeping task in the Internet of Things world and keep both your grain universe and related LOB systems (in my case ACS) as clean as possible and maintain Orleans in state where it is an exact representation of your real IT assets.

Happy coding!