How to use actors in distributed applications

Actors make it easier to build and manage scalable, distributed cloud applications. Each actor can send and receive messages and taking certain actions based on message contents

How to use actors in distributed applications

Building for the cloud and for scalability means building a different type of application. Instead of constructing monolithic applications, you need to break code up into collections of services that can scale out across the compute fabric of a public or private cloud.

Yet such distributed systems have their own problems. Depending on the application, you may need to solve complex issues of managing state in an unpredictable, failure-prone environment -- one where the underlying fabric of virtual infrastructures may be pre-empted at any time.

Developers looking to build distributed systems quickly discover that the models and patterns we use for the current generation of applications don't scale. You wouldn't use an n-tier MVC architecture to power a distributed sensor network, for example, or an MVVM framework to handle an international VoIP service.

That's where the actor-message pattern comes in. The concept was born in 1973, and it's becoming increasingly popular -- you'll find it embedded in the Project Orleans tools from Microsoft Research and in such modern languages as Erlang.

Getting to know the actor

The actor is an important concept in distributed application development. It builds on the idea that everything is capable of receiving and sending messages and acting on the content of those messages. Concurrency is handled by the messages in a system, because there's no way of managing arrival order -- an important point to understand in preparation for the massive networks we'll need to manage when the Internet of things arrives.

Actors are relatively simple pieces of code that can be implemented using familiar programming tools and techniques. Microsoft .Net developers will find C#'s async/wait pairing a useful tool, while similar constructs in Go and Erlang enable developers to create message-handling APIs. Similarly, modern, lightweight publish-and-subscribe systems like MQTT can act as a backbone for actor-message implementations.

These solutions provide a framework for reliable message delivery along with a set of tools that enable systems to spawn new actors quickly when they're needed, as well as kill unneeded endpoints when systems scale back from peak loads.

Simple code also maps well to the relatively dumb world of the Internet of things, where servers and services need to work with devices that might have no OS, possess very little memory, or use something other than standard Internet protocols.

Working with actors

The actor model maps neatly to the stateless microservices world of PaaS. What's especially useful is that if you're using common agile methodologies, such as user stories, an actor is able to implement the key elements of a story -- processing inputs and delivering appropriate outputs, wrapping relatively simple business logic, and passing state to simple storage services.

You can quickly go from a user story to an actor API definition, complete with message semantics. Mapping the resulting actors and messages to microservices becomes relatively trivial, and the message-first approach to actor design makes it possible to quickly define idempotent APIs and use them as the basis of a microservice design. Working with in-memory NoSQL systems gives you a framework for handling state, and passing state elements between actors by using messages to pass pointers.

One way to start thinking about actor development is to consider how existing Web services map to actors and decomposing those services into microservices. If you consider a RESTful (or even a SOAP) Web service endpoint as an actor message API, and an HTTP get or PUT with JSON as a message, you may well have already begun implementing actors, and only need to build your existing services on a distributed computing platform to take advantage of cloud fabrics and scale.

Be aware that there are problems inherent to the default actor model. You're going to need to have some form of management framework to handle actor creation and destruction, as well as ensure that the system scales effectively. You won't have that if you use Erlang directly, for example; you're going to need to develop your own management framework or use a more complex environment like Akka.

Finally, there's no getting around the fact that you need to understand distributed system development concepts. This can be a significant hurdle for many developers.

Getting the most our of actors

Such obstacles aside, the actor model is a powerful tool that makes it easier to build and manage scalable cloud applications.

The reliable actor model that Microsoft uses in its Azure Service Fabric is based on research work for the Project Orleans virtual actor model, which adds an additional layer of abstraction to the actor pattern.

Unlike traditional actors, a virtual actor is perhaps best thought of as a permanent message address. If an endpoint doesn't exist, it's automatically created -- on any server that's being used to host the application -- giving you automatic failover, which is conducive to working on unreliable cloud fabrics where compute resources can be pre-empted by the underlying scheduler.

Remember that building distributed applications isn't easy, even if you're using actor-driven microservices. While they many help manage concurrency and scalability, you're still going to need to consider how to keep your systems consistent.

In practice that means using actors as scalable service endpoints, marshalling and feeding data into more complex services, and allowing massive data feeds to be turned into actionable information. The end result, however, is that you can manage hundreds and thousands of information sources with very little code.

Copyright © 2015 IDG Communications, Inc.