Bernie Cook's Blog

Azure, C#, .NET, Architecture & Related Tech News

Distributed Design: Applying the Command Pattern to Azure’s Web/Worker Roles

Leave a comment

WorkerRoleOne place I regularly come across the use of the Command pattern is when working on Azure projects that employ worker roles to execute long running tasks initiated by a scheduled process or user action. The Command pattern lends itself to the distributed nature of these solutions with very little plumbing required when working in Azure.

The following post provides a sample application; CommandQueue which contains 3 examples of a web and worker role utilising the Command pattern. The web role is designed to provide a rapid responses to the user, offloading any lengthy operations to the worker role. The source code for the CommandQueue solution is available on GitHub so feel free to clone, compile and execute it while working through this post.

Before I start in on the code I’ll provide a brief foreword on software design patterns (which you can skip if you’re already familiar with them) followed by the theory behind the Command pattern. Having the theory in place will help when it comes to understanding the distributed design and underlying code.

A Brief Word on Design Patterns

If you’ve spent any time with design patterns then you’ll know they’re a template for solving a problem within a given context. At times they won’t give you a perfect solution but will most certainly provide the best one, as long as they’re applied correctly 🙂

If you haven’t spent any time with design patterns then there are a number of good texts on the market, as well as the usual online resources, to get you started. I’d recommend books over general internet browsing if you want to familiarise yourself with a collection of design patterns as you may find the consistency of presentation easier to digest than a variety of different interpretations across a variety of websites. Some design patterns can get quite involved and if they’re not explained properly you’ll find yourself spending more time banging your head against a wall then joining the dots on how they might be of use. Two texts I can personally recommend are “Design Patterns Explained” by Shalloway and Trott, and “Head First Design Patterns” by Freeman, Robson, Bates and Sierra. Add to that the Pluralsight tutorials on design patterns and OOP by Steve Smith.

Command Pattern

Simply put a Command pattern is one in which a request is encapsulated so that it can be executed at a later point in time. A “request” can be a number of things and a broad definition is usually the best one to adopt, i.e. it could be as simple as a request to write a number of log entries, a request to perform some data mining which ultimately produces a number of PDF documents which are emailed to several recipients … the list goes on. The jist being that it is always a request that you can perform at another point in time, and most likely a lengthy process you’ll want to offload so it doesn’t hold up another event such as a user awaiting a response from an action that generated the request.

The implementation of the Command pattern can vary significantly across languages and even within the .NET framework. As long as you understand the theory and concepts behind the Command pattern, and how to apply it with your preferred framework and language(s), then you’ll be on the right track.

The 4 key Command pattern elements that you need to know:

  • Client – It tells the command what receiver it’s going to use
  • Invoker – It prompts the command object to execute its encapsulated request
  • Receiver – The class which does the work when the command is executed by the Client
  • Command – A concrete implementation of a Command interface – the typical concrete implementation of the Execute() method calls the Receiver

Don’t be concerned if this doesn’t make a whole lot of immediate sense. I usually find myself staring at a new design pattern description for far too long before a working example provides me with an “ah, I’ve got it” moment.

In this post I purposefully did away with the class and sequence diagrams that sometimes accompany a design pattern explanation (and the Gang of Four definition) opting more for a more hands-on approach. If you’re interested though in the former approach do take a trip over to Wikipedia’s Command pattern page.

The last thing to cover before moving onto the sample application is the following high-level diagram. This diagram illustrates when and where the Command pattern elements are employed across this post’s distributed solution. In short the web role addresses the UI/immediate response to a request, and the worker role takes care of the request initiated by the web role. The requests, in this case they’re long running processes, are placed in Azure queue storage – which provides a common ground between the two roles.

The Solution

VisualStudio-SolutionExplorerThe sample solution constructed for this post consists of 3 projects:

1. Web Role
2. Class Project
3. Worker Role

The web role contains the 3 UI example interfaces, each initiating a single request against the solution via a respective API controller.

The class project contains a respective service for each API controller, acting as the Command pattern client by populating a given entity which is then passed to a given command object. The services also place the commands in a queue for the worker role to process.

The worker role scans several queues for new commands then acts as the invoker by calling the command object’s execute method. The execute method then calls the receiver which in turn performs the work encapsulated in the request.

I’ll now walk through the first of the 3 examples to better illustrate the Command pattern at work. Please keep in mind these are simplified samples, engineered for this post, so you won’t find they typical guard clauses, logging, dependency injection or other elements that typically accompany a real-world application.

Example 1

The first example will contain a bit more explanation, and I’ll impart some tips along the way.
Command Queue ScreenshotSo firing up the solution displays the above page. By clicking on the “Leave Reply” button in the left-most example the following sequence of events occur (keep in mind that multiple instances of our worker role are running in the background):

1. The “Leave Reply” click event is handled by some jQuery which takes the Example .1 input values and wraps them up into a JSON string. The jQuery then makes an AJAX call, posting the JSON string to an API controller action method. I haven’t listed the source code here but do feel free to view the CSHTML code on GitHub as well as the API controller method’s view model.

2. The API controller’s action method checks the populated view model has a valid state before calling a service method that receives the parameters.

BlogPostController.cs

using CommandQueue.Domain.Interfaces;
using CommandQueue.Domain.Services;
using CommandQueue.Web.Models.SimulationModels;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace CommandQueue.Web.ApiControllers
{
    public class BlogPostController : ApiController
    {
        private readonly IBlogPostService _blogPost;

        public BlogPostController()
        {
            // Use DI here.
            _blogPost = new BlogPostService();
        }

        //
        // POST: /api/blog-post/leave-reply/

        [ActionName("leave-reply")]
        public HttpResponseMessage Post(
            LeaveReplyModel leaveReplyModel)
        {
            if (ModelState.IsValid)
            {
                _blogPost.LeaveReply(
                    leaveReplyModel.Reply,
                    leaveReplyModel.EmailAddress);

                return new HttpResponseMessage(HttpStatusCode.OK);
            }

            return new HttpResponseMessage(HttpStatusCode.BadRequest);
        }
    }
}

3. The service method performs several actions; it creates an entity, persists the entity to Azure table storage, creates a command object (populating it with the entity) and then places the command object (our request) in an Azure queue. The parts highlighted in bold represent the actions of the Command pattern’s client – telling the command object what it’s going to be doing.

BlogPostService.cs

using CommandQueue.Domain.Azure;
using CommandQueue.Domain.Command;
using CommandQueue.Domain.Interfaces;
using CommandQueue.Domain.Model;

namespace CommandQueue.Domain.Services
{
    public class BlogPostService : IBlogPostService
    {
        /// <summary>
        /// Leave a reply for the designated recipients.
        /// </summary>
        /// <param name="reply">Reply to be left.</param>
        /// <param name="emailAddress">User's email address.</param>
        public void LeaveReply(
            string reply,
            string emailAddress)
        {
            // Persist the data to table storage.
            var blogPostReplyEntity = new BlogPostReplyEntity
                {
                    Reply = reply,
                    EmailAddress = emailAddress
                };

            var table = new Table();
            table.AddEntity(blogPostReplyEntity);

            // Create the command object.
            var dispatchMessageCommand = new NewBlogPostReplyCommand
                {
                    BlogPostReplyEntity = blogPostReplyEntity
                };

            // Add the command into queue storage, for later processing.
            var queue = new Queue();
            queue.AddMessage(dispatchMessageCommand);
        }
    }
}

4. I’ve simplified the Queue class’ AddMessage(), called at the end of the above method, so it takes any concrete command object and stores a serialized version in a queue named after the command object’s class. A screenshot of how the serialized messages appear in Cloud Storage Studio 2 is provided.

Queue.cs

/// <summary>
/// Add a new message to the queue.
/// </summary>
/// <param name="command">Command message to add.</param>
public void AddMessage(
	ICommand command)
{
	var queue = GetQueueReference(command.GetType().Name);
	var message = new CloudQueueMessage(JsonConvert.SerializeObject(command));

	queue.AddMessage(message);
}

5. The worker role (which I’ve simplified again) trawls through existing queues that are named after any existing classes that implement the ICommand interface. It lifts any command messages out of the queue and then deserializes them before they’re executed. The “executed” part is the role of the invoker.

WorkerRole.cs

namespace CommandQueue.Worker
{
    public class WorkerRole : RoleEntryPoint
    {
        public override void Run()
        {
            var queue = new Queue();
            var commandInterface = typeof(ICommand);
            var commandTypes = (from assembly in AppDomain.CurrentDomain.GetAssemblies()
                                from type in assembly.GetTypes()
                                where (commandInterface.IsAssignableFrom(type)) && (commandInterface != type) select type).ToList();

            while (true)
            {
                try
                {
                    foreach (var commandType in commandTypes)
                    {
                        var message = queue.GetMessage(commandType.Name, 4);

                        if (message != null)
                        {
                            dynamic command = JsonConvert.DeserializeObject(message.AsString, commandType);
                            command.Execute();

                            queue.DeleteMessage(commandType.Name, message);
                        }
                    }
                }
                catch (Exception exception)
                {
                    Trace.TraceError(exception.Message);
                }

                Thread.Sleep(1000);
            }
        }

        public override bool OnStart()
        {
            ServicePointManager.DefaultConnectionLimit = 12;

            return base.OnStart();
        }
    }
}

6. The Execute() method’s logic varies for each concrete command and in this case, because the worker role has deserialized a NewBlogPostReplyCommand instance, it takes the format provided below. The ICommand interface can come in a number of different formats but you can pretty much guarantee that you’ll always find an Execute() method of some variation that must be implemented:

NewBlogPostReplyCommand .cs

namespace CommandQueue.Domain.Command
{
    public class NewBlogPostReplyCommand : ICommand
    {
        public BlogPostReplyEntity BlogPostReplyEntity { get; set; }

        public void Execute()
        {
            BlogPostReplyEntity.NotifyModerators();
        }
    }
}

7. The Execute() method in turn calls the contained BlogPostReplyEntity’s NotifyModerators() method, which is the receiver. Because of the way we’ve encapsulated the request the entity is already populated (thanks to the deserializing by the worker role) so the entity’s state is made available to the receiver.

BlogPostReplyEntity.cs

using CommandQueue.Domain.Azure;
using Microsoft.WindowsAzure.Storage.Table;
using System;
using System.Diagnostics;

namespace CommandQueue.Domain.Model
{
    public class BlogPostReplyEntity : TableEntity
    {
        public string Reply { get; set; }
        public string EmailAddress { get; set; }
        public bool ModeratorsNotified { get; set; }
        public bool Authorised { get; set; }
        public DateTime? ModeratorsNotifiedDateTime { get; set; }
        public DateTime? AuthorisedDateTime { get; set; }
        public DateTime AddedDateTime { get; set; }

        public BlogPostReplyEntity()
        {
            PartitionKey = Guid.NewGuid().ToString();
            RowKey = PartitionKey;

            ModeratorsNotified = false;
            ModeratorsNotifiedDateTime = null;

            Authorised = false;
            AuthorisedDateTime = null;

            AddedDateTime = DateTime.UtcNow;
        }

        /// <summary>
        /// Notify all moderators that a new blog post reply needs to be moderated.
        /// </summary>
        public void NotifyModerators()
        {
            // Fabricate some moderators.
            var moderators = new[]
                {
                    new { Name = "Luke Skywalker", EmailAddress = "lukeskywalker@galactic-senate.com" },
                    new { Name = "Han Solo", EmailAddress = "hansolo@galactic-senate.com" },
                    new { Name = "Leia Skywalker", EmailAddress = "leiaskywalker@galactic-senate.com" }
                };
 
            foreach (var moderator in moderators)
            {
                SendModeratorNotificationMessage(moderator.Name, moderator.EmailAddress);
            }

            FlagAsModeratorNotified();
        }

        /// <summary>
        /// Send a moderator notification message.
        /// </summary>
        /// <param name="moderatorName">Moderator's name.</param>
        /// <param name="moderatorEmailAddress">Moderator's email address.</param>
        private void SendModeratorNotificationMessage(
            string moderatorName,
            string moderatorEmailAddress)
        {
            Debug.WriteLine("Send notification message to '{0}' at '{1}' for the blog post reply: '{2}' from: '{3}'",
                moderatorName,
                moderatorEmailAddress,
                Reply,
                EmailAddress);
        }

        /// <summary>
        /// Flag the blog post reply as having had the relevant moderator's notified.
        /// </summary>
        private void FlagAsModeratorNotified()
        {
            ModeratorsNotified = true;
            ModeratorsNotifiedDateTime = DateTime.UtcNow;

            var table = new Table();
            table.ReplaceEntity(this);
        }
    }
}

And that’s it. I’ve bolded the four key elements so you can see the client, invoker, receiver and command objects in play.

Hopefully this makes it clear how the Command pattern’s request, in this case the blog reply, is encapsulated and executed at a later time within a distributed solution hosted in Azure.

I probably wouldn’t class this as overly long running process but it’s certainly a request that you don’t to make the user wait for it to complete. Do keep in mind that the Command pattern doesn’t need to be applied to “long running” requests only. If you have a request that can be executed later, and you have the infrastructure and available skills to do so, then it’s definitely worth considering.

If you’re wondering why I persisted the entity into a NoSQL store like Azure table storage then congratulations, it’s a good question? It has nothing to do with the Command pattern per se, however it is something I added in to expand on the complexity of the example.

In summary there isn’t a great deal of complexity to the Command pattern, and once you understand how to apply it to some fundamental Azure features (queues and worker roles), then you can combine them to address a number of common tasks.

Examples 2 and 3

I won’t go into any depth on the other two examples in this post. They are variations on the first example and further illustrate the application of the Command pattern. They do compile and run without error so do clone the CommandQueue solution from GitHub and have a look through each example.

Concluding Points

A few things worth pointing out:

  • As noted earlier there are a number of ways of utilising the Command pattern, this post focuses on one which utilises a good part of the core Azure feature set.
  • The beauty of this approach is that the entity’s behaviour and state isn’t spread across the solution, it’s encapsulated within the entity itself, avoiding an anaemic domain model design (DDD lingo)
  • A standard ICommand interface exists in the System.Windows.Input namespace that you can use if you don’t want to roll your own.
  • When designing an Azure solution you may find it useful to draw an architectural diagram using Visio. I’ve referenced a number of Visio Azure resources in a previous post to get you started “Azure Visio Shapes & Stencils“.
    Distributed Architecture Diagram
Advertisements

Author: Bernie

I currently live and work in the UK, just outside of London. I've been working in IT for 15+ years and in that time have solved many technical problems via blogs, forums, tutorials etc. and feel like I should be giving something back. This blog post is my way of contributing and I hope it proves just as useful to others as their contributions have to me.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s