First, here is the base class for all actors.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
As you can see, I simply used Runnable as the type of the messages.
The Actor itself is Runnable, meaning that it can be submitted to the thread pool. When executed :
- it tries to handle a message from the mailbox if there is one.
- It then re-submits the actor itself
This ensures that only one thread is executing messages on an actor at a given time, and it also avoids spawning new thread for every new actor.
As an example, here is how I used this to make an actor of an existing InProcessChatRoom class.
1 2 3 4
1 2 3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
ChatRoomActor is in fact some kind of proxy to use from other actors to send messages to the chat room.
As with any implementation of the Actors Model, the neet thing is the separation of threading and logic. That makes it so much simpler ! (You can get more detail about the complexity I am talking about by taking a look at the concurrency-kata)
Here is a performance summary of this implementation compared to others on a “throughput vs clients” benchmark of the style “Enter while others are talking”
Results can be disappointing compared to other implementations but the example itself is a bit misleading. The chatroom does exclusively message passing, there is not much computation to parallelize, in a different setting, the results would have been completely different.
As you can see, this implementation is just a quick prototype, nothing production ready. Here are the main limitations I can think of right now :
- It uses Busy Waiting for the next message, meaning that it consumes unnecessary resources, and that more important messages to other Actors might be delayed
- Usually, actor messages are selected on their type rather than on their order of arrival, this is not the case here
- The usage of the Runnable interface as base message type, though handy, opens the door to inter-thread calls that might violate the model altogether
- There is absolutely no support of out of process actors until the messages are Serializable
So if you want to learn more about different models of concurrency, you are welcome to have a look at the How-To section in the README file.
On my part, although it was a lot more work than I would have guessed at the beginning, I barely scratch the surface of the subject ! I could now :
- extract the CSP or Actor implementation and make them more robust
- practice and present the whole kata as a 2 hours live coding session
- prepare a hands-on training about concurrency
So, if you are willing to do any of the above you are welcome to contribute !