Actors can be fixed

How do you keep your actor system from falling apart when things go wrong?

The short answer is Supervision.

What Is Supervision, and Why Should You Care?

What Is Supervision?

“Look at this mess you made. Now clean it up and start over!”

Just kidding. You’re doing great. Relax.

But I bet you’ve heard (and probably said) something similar before. That’s similar to supervision in the actor model: a parent monitors its children for errors, and decides how to clean up messes when they happen.

Actors must be supervised!

Why Should You Care?

Supervision is the basic concept that allows your actor system to quickly isolate and recover from failures.

Supervision from the top to the bottom of the actor hierarchy ensures that when part of your application encounters an unexpected failure (unhandled exception, network timeout, etc.) those failures will be contained to only the affected part of your actor hierarchy. All other actors will keep on working as though nothing happened. We call this “failure isolation.”

How is this accomplished? Let’s find out…

One of the first questions developers ask once they learn how Akka.NET actors work is

If actors can only process one message at a time, can I still use async methods or Task<T> objects inside my actors?

The answer is yes! You can still use asynchronous methods and Task<T> objects inside your actors - using the PipeTo pattern!

(2/05/2022) Update

We have completely revised our guidance around await vs. PipeTo in our latest post”: Async / Await vs. PipeTo in Akka.NET Actors

(8/20/2016) Update

Since Akka.NET 1.0 was released, Akka.NET actors have fully supported async / await inside actors. But there’s a catch involved. We still strongly recommend PipeTo over asyc / await for performance and cohesion reasons but there are scenarios where the latter makes life easier. Keep reading!

Actors Process Messages One at A Time

So actors process the contents of their inbox like this:

Animation - Akka.NET actors processing messages in their inbox

The actor’s mailbox pushes a new message into the actor’s OnReceive method once the previous call to OnReceive exits.

This is an important concept, because this is how Akka.NET enforces thread-safety for all of the code that executes inside an actor - by making sure an actor’s message processing code (OnReceive) can only be run one invocation at a time.

That being said, it’s still possible to take advantage of async methods and methods that return Task<T> objects inside the OnReceive method - you just have to use the PipeTo extension method!

When I write about Akka.NET and the actor model, this is not what I mean:

Not the right kind of Actor model

I’m probably going to abuse this stupid joke in every 100-level blog post and video where I introduce the concept of Actors, so please bear with me.

In all seriousness, an actor is a broad concept. Here’s my layman’s definition of the actor model:

An “actor” is really just an analog for human participants in a system. Actors communicate with each other just like how humans do, by exchanging messages. Actors, like humans, can do work between messages.

Think of something like a call center, where hundreds of customers might call a 1-800 number and have concurrent conversations with one of many possible customer service agents.

It’s been a massive year for Akka.NET and I want to highlight some of the amazing contributions that have been made to that project. I’m writing this post from my perspective, but it’s not about me.

This month marks the one-year anniversary of Akka.NET and it has been a massive year for Akka.NET. In December of 2013, Roger Alsing and I had never met and we were both working on our own actor framework implementations in .NET.

Before It Was Akka.NET…

My startup at the time, MarkedUp Analytics, was just starting its R&D efforts to begin developing its real-time marketing automation product on top of our existing in-app analytics product. We knew we needed the Actor model and reliable socket networking software to make the product meet its business requirements, and so I began work on two projects in parallel:

I broke ground on Helios first, right around Thanskgiving 2013. By Christmas Eve I also had a working prototype of Hyperion, who’s actor model implementation was largely powered by the TPL Dataflow library. One weekend in late January, as I was resuming work on Hyperion after taking a break since Christmas, I came across a blog post some guy named Roger Alsing wrote about his port of Akka Actors to .NET.

I cared way more about getting MarkedUp’s in-app marketing product shipped than I did creating my own Actor framework, so I did what anyone in my position would do: furiously port one of...