5. The Model of Actor Model
A way of reasoning about concurrent computation
6. What is the Actor Model
A way of reasoning about concurrent computation
Is inherently concurrent
7. The Model of Actor Model
Is a conceptual model for reasoning about concurrent
computation
Is inherently concurrent
Manages concurrency through message passing
8. The Model of Actor Model
Is a conceptual model for reasoning about concurrent
computation
Adopts the philosophy that everything is an actor
Is inherently concurrent
Manages concurrency through message passing
9. What is an Actor?
Lightweight
Never shares state
Communicates through asynchronous
messages
Has a mailbox to buffer messages
Processes one message at a time
Is a single-thread object
12. The overview
Akka.NET
• A port of Java/Scala Akka
• Open source
• Task Parallel Library
• Reactive methodology
• Can be run within an application,
on-prem or in the cloud(?)
13. The overview
Orleans
• Started by Microsoft Research
• Open source
• Task Parallel Library
• Reactive methodology
• Cloud-native
Akka.NET
• A port of Java/Scala Akka
• Open source
• Task Parallel Library
• Reactive methodology
• Can be run within an application, on-
prem or in the cloud(?)
23. Akka.NET: An Actor is Actor
Must be explicitly created and stopped
Are created in the context of their parent
24. Akka.NET: An Actor is Actor
Must be explicitly created and stopped
Are created in the context of their parent
Exposes a set of life-cycle hooks
25. Akka.NET: An Actor is Actor
Must be explicitly created and stopped
Are created in the context of their parent
Exposes a set of life-cycle hooks
Are location transparent
akka.tcp://Demo@127.0.0.1:12345/user/HelloWorld/$c
28. Orleans – creating a grain
• In Visual Studio create two projects
• One for your grain interfaces
• One for your grain implementations
• In both projects install the NuGet package
Microsoft.Orleans.OrleansCodeGenerator.build
29. Create a Grain interface
public interface IHelloWorld : IGrainWithIntegerKey
{
Task Greeting(string name);
Task<string> ReturnGreeting(string name);
}
Must implement one of the
following:
• IGrainWithIntegerKey
• IGrainWithGuidKey
• IGrainWithStringKey
• IGrainWithIntegerCompoundKey
• IGrainWithGuidCompoundKey
30. Create an implementation of the interface
public class HelloWorldGrain : Grain, IHelloWorld
{
public Task Greeting(string name)
{
Console.WriteLine($"Hi {name} from Orleans");
return TaskDone.Done;
}
public Task<string> ReturnGreeting(string name)
{
return Task.FromResult($"Hi {name} from Orleans");
}
}
31. Interacting with Grains
static async Task SendMessage(User user )
{
var helloWorld = GrainClient.GrainFactory.GetGrain<IHelloWorld>(0);
var response = await helloWorld.Greeting(user);
WriteLine(response);
}
33. Akka.Net – creating an actor
• In Visual Studio:
• Create a new class library
• Create a console application
• Import the core Akka.NET Nuget package: Akka
34. Create message
public class HelloUserMessage
{
public User User { get; }
public HelloUserMessage(User user)
{
User = user;
}
}
35. Create an actor
public class HelloWorldActor : ReceiveActor
{
private TimeSpan _waitPeriod;
public HelloWorldActor(TimeSpan waitPeriod)
{
_waitPeriod = waitPeriod;
Receive<HelloUserMessage>(m =>
{
var user = m.User;
Thread.Sleep(_waitPeriod);
WriteLine($"Hi {user.Id} {user.FirstName} nice to meet you [on thread ");
});
Receive<DataCompleted>(m => WriteLine("Data is completed"));
}
36. Using the actor
var system = ActorSystem.Create("demo")
var helloWorld = system.ActorOf(Props.Create(() => new HelloWorldActor()));
helloWorld.Tell(new HelloUserMessage(new User());
await system.Terminate();
42. Bits and Pieces
“let it crash” and exception handling
Persisting state
Changing behaviour
Grains for everyone
Routing in Akka.NET
Clustering in Akka.NET
Why has the actor model appeared to suddenly become the flavour of the month?
Because multi-threaded concurrency is hard and distributed multi-threaded concurrency is harder again.
Shared state
Race conditions
lock and deadlocks
hard to understand and maintain
not easily distributed.
In the .NET ecosystem the three best known frameworks that in one form or another implement the actor model are service fabric, akka.net and Microsoft Orleans. It is these last two that we are looking at today.
In this talk we really only to skim the surface of either of these frame works
First proposed by Hewitt, Bishop and Steiger in 1973 as a mathematical theory of computation.
Another key feature of the actor model is the concept of distribution. Given an actor is a single unit of code with a mailbox and an internal state, whether that actor running locally or on a remote node is irrelevant to the sender. As long as the message gets there what does it matter?
An Actor is a primitive unit of computation
<click slides>
In addition to characteristics an actor
Can create other actors
Can send messages to other actors
Can change its behaviour to determine what to do with the next message
Another key feature of the actor model is the concept of distribution. Given an actor is a single unit of code with a mailbox and an internal state, whether that actor running locally or on a remote node is irrelevant to the sender. As long as the message gets there what does it matter?
“One actor is no actor, they come in systems, and they have to have addresses so that one actor can send messages to another actor.”
– Carl Hewitt
Having got the preliminaries out of the way time to dig into Orleans and Akka.net
And have a look at how they both compare with each other and how they have approached implementing the Actor Model.
So as you can see there is at least on the surface some similarities but in many ways that is where it ends.
To paraphrase from Dr. Roland Kuhn's article comparing Orleans and Akka actors;
with Orleans the primary focus is to simplify distributed computing so that non-experts can write efficient, scalable and reliable distributed services.
Akka on the other hand is toolkit for creating distributed systems offering full control over the domain but also exposing its inherent complexity.
In other words Orleans provides a relatively low entry point into the actor model paradigm for developers from an OO background whereas Akka.net requires you rethink your approach to programing.
Akka uses a supervisor hierarchy
Silos are more like a commune where actors exist as independent think of it like a bucket of actors
an actor is a logical unit of computation and in terms of the key characteristics that make up an actor, lightweight, single threaded, no shared state, etc. Orleans and Akka.NET are pretty much on par but after that their respective implementations are radically diverge reflecting the differences in their design philosophy.
In Orleans what we have been referring to as an actor is Grain. This difference in terminology reflects the difference in how The Developers of Orleans have approached the problem.
A grain is also referred to as a virtual actor as it may or not exist it any point in time.
Within Orleans if a grain has been idle for a period of time it will be garbage collected to free up memory. In terms of lifecycle grains are either activated or deactivated, They can never be programmatically started or stopped.
Such as:
PreStart
PostStop
PreRestart
PostRestart
In Akka.NET Actors explicitly communicate via messages. And by convention should be immutable (though this is currently not enforced)
In Orleans the existence of a message is not so obvious and I have to admit this bothers me a little.
When a grain method is invoked, the Orleans runtime makes a deep copy of the method arguments and forms the request out of the copies. This protects against the calling code modifying the argument objects before the data is passed to the called grain.
The Orleans.Concurrency.Immutable wrapper class