The actor model is an approach to designing concurrent systems that has been around since the early 70's, but is gaining more popularity today. Being a message-based approach, the actor model fits nicely when building out transactional or multi-step workflow process systems. Message-driven actor systems take a lot of the complexity away and allow you to create small classes (actors) that handle very specific tasks. These actors are coordinated via the passing of immutable messages, which allows your system to scale out if needed. In this talk, we’ll look at a popular .NET actor system Akka.NET and, through several simple examples, show you how to get started building scalable message-driven solutions.
2. ABOUT ME
5-Time .NET (Visual C#) MVP (April 2011)
Sr. Solutions Architect at Confluence
One of the organizers for Pittsburgh TechFest (http://pghtechfest.com)
Organizer of Pittsburgh Reactive Dev Group (http://meetup.com/reactive)
Past President of Pittsburgh .NET Users Group
Twitter - @DavidHoerster
Blog – http://blog.agileways.com
Email – david@agileways.com
3. AGENDA
Messages as Part of Application Design
Being Reactive
What the Actor Model Provides
Hello Akka.NET
Working with Akka.NET
Cross-Process Actor Systems (Akka.Remote)
4. CQRS
Command Query Responsibility Segregation
Coined by Greg Young
Evolution of CQS (Command Query Separation)
Coined by Bertrand Meyer
Both revolve around the separation of writes (command) and reads
(query)
CQS is more at the unit level
CQRS is at the bounded context level, or so
5. MESSAGES
The core of CQRS Messages
Communication from the service layer to the domain via commands
Command handlers could also update the underlying repository
As actions happen, events are raised
Event handlers could issue other commands
Event handlers could update the underlying repository
6. MESSAGES
Regardless of how it’s implemented, communication between
application parts is via messages
Not only helps communicate intent of the action
“PublishWidget”, “ExpireWorkItem”, “UpdateDefinition”, “DefinitionUpdated”
But allows for remote handling of messages
Queue, REST payload, etc.
8. SO?
So how does this affect my system design?
Let’s consider some procedural pitfalls
9. WORD COUNTER EXAMPLE
Simple program to count the occurrences of words in a document
Print out the top 25 words and their counts at the end
Can be accomplished easily via procedural code
11. WORD COUNTER EXAMPLE
What if you wanted to spread out the counting load?
What if you wanted to scale out to other nodes/processes/machines?
Fault tolerance, concurrent actions, etc.?
12. BUILDING CONCURRENT APPS
In word counter, may need to spawn some threads
Lock some critical sections, etc.
The system becomes responsible for knowing everything going on
Very Proactive (not Reactive!) system
13. SIDE NOTE: REACTIVE VS.
PROACTIVE
Isn’t proactive a good thing?
A system taking upon itself to
check state is proactive
It’s doing too much
A reactive system reacts to
events that occur
It’s doing just the right amount
14. SIDE NOTE: REACTIVE VS.
PROACTIVE
Isn’t proactive a good thing?
A system taking upon itself to
check state is proactive
It’s doing too much
A reactive system reacts to
events that occur
It’s doing just the right amount
System
EvtEvt
System
EvtEvt
Proactive
Reactive
15. REAL WORLD SCENARIO
Loosely structured data
Multiple files to combine
Operations to perform during the projection process
17. REAL WORLD SCENARIO
Number of “steps”
May need some sub-steps
Can be broken down into individual pieces
Actors
Communicate via messages for loose coupling
19. ACTOR MODEL
Actor Model is a system made of small units of concurrent
computation
Formulated in the early 70’s
Each unit is an actor
Communicates to each other via messages
Actors can have children, which they can supervise
20. WHAT IS AN ACTOR?
Class that encapsulates state and behavior
State can be persisted (Akka.Persistence)
Behavior can be switched (Become/Unbecome)
Has a mailbox to receive messages
Ordered delivery by default
Queue
Can create child actors
Has a supervisory strategy for child actors
How to handle misbehaving children
Are always thread safe
Have a lifecycle
Started, stopped, restarted
21. AKKA.NET
Akka.NET is an open source framework
Actor Model for .NET
Port of Akka (for JVM/Scala)
http://getakka.net
NuGet package – search for Akka.Net (not the first result usually!)
22. STARTING WITH AKKA.NET
Akka.NET is a hierarchical system
Root of the system is ActorSystem
Expensive to instantiate – create and hold!
ActorSystem can then be used to create Actors
23. CREATING AN ACTOR
An Actor has a unique address
Can be accessed/communicated to like a URI
Call ActorOf off ActorSystem, provide it a name
URI (actor path) is created hierarchically
Actor Path = akka://myName/user/announcer
24. SENDING A MESSAGE
Messages are basis of actor communication
Should be IMMUTABLE!!!
“Tell” an actor a message
Async call
Immutable!!
25. RECEIVING A MESSAGE
Create your Actor
Derive from ReceiveActor
In constructor, register your
message subscriptions
26. RECEIVING A MESSAGE
Each actor has a mailbox
Messages are received in the actor’s mailbox (queue)
Actor is notified that there’s a message
It receives the message
Takes it out of the mailbox
Next one is queued up
Ordered delivery by default
Other mailboxes (like Priority) that are out-of-order
Actor
Mailbox
Msg
28. CREATING CHILDREN
Best to call ActorOf to get an IActorRef
Create a static Props creator
Actor path is relative to parent’s actor path
akka://myDemo/user/countChocula/{childName}
When creating a child, good idea to name it
So you can reference it later!
29. WORD COUNTER WITH ACTORS
Program sends StartCount message to CountSupervisor
CountSupervisor, for each line, sends line to one of 5 LineCounterActors
(ReadLineForCounting message)
LineCounterActor counts the word in that line
Tells the Sender (CountSupervisor) the results (MappedList message)
CountSupervisor aggregates results of MappedList messages
When all lines complete, CountSupervisor sends each LineActor a Complete
message
LineCounterActor cleans up and sends CountSupervisor Complete
When all LineCounterActors are Complete, CountSupervisor prints out top 25
words
31. ROUTING
Map Reduce example used Round Robin
There are others OOTB
Broadcast
Random
Consistent Hashing (used by Cluster)
Smallest Mailbox
More
Pools and Groups
Pools are more anonymous
Groups are pre-created
32. FINDING CHILDREN
Within an actor, call Context.Child with the name of the child actor
If not found, ActorRefs.Nobody is returned
If found, you have an IActorRef to work with
Using ActorSelection doesn’t guarantee actor is initialized
33. MORE COMPLEX ACTOR DEMO
baseball
gameCoo
rdinator
gameInfo
-x
gameInfo
-y
playerSup
ervisor
batter-abatter-bbatter-c
c-01 c-11 c-32
34. INTEGRATION
Integration with other systems is simple
Best to encapsulate in its own actor
Contain any errors there
Prevent affecting parts of the system further upstream
35. ASYNC
Actors have messages delivered to them in order via a Mailbox
As message is received, handed to Actor to process
Messages in mailbox queue up
As a result, async processing of messages isn’t possible
Receive<> (async msg => { … }) doesn’t work
If you need to perform async tasks within Receive
PipeTo(Self) usually does the trick
Re-queues message back on Mailbox
When delivered, actor resumes
Actor
Mailbox
Msg
PipeTo
36. ACTORS ACROSS PROCESSES
Akka.Remote module
Configure via HOCON
Human Optimized Configuration Object Notation
Allows an actor system to distribute messages to actors across
processes
Location transparency!!
38. ACTORS ACROSS PROCESSES
Actor Path modified
akka.tcp://localhost:50000@{system}/user/{supervisor}/{name}
Protocol and location added to actor path
Protocol defaults to tcp, but you can provide your own
Actor path above is remote path
42. ASKING AN ACTOR
Wait for a response from an actor
Somewhat of an anti-pattern for Actor Model
If used, use sparingly
43. HANDLING ERRORS
An exception during processing with a classic app could crash the
whole system
An exception within a child actor is isolated
44. IS AKKA.NET…?
Pub/Sub?
No, but it could be
Message Bus, like RabbitMQ or MassTransit
Uses messages to communicate
Message bus concerned with building a distributed system topology
Storm, ETL/ELT, etc.?
Kind of
Can build system like that with Akka.NET