Acting like I don't get the message :-/

389 views
Skip to first unread message

Jan Bols

unread,
Sep 28, 2013, 4:44:44 PM9/28/13
to ddd...@googlegroups.com
I'll make a confession: this is a cross post from the yahoo ddd user group. I didn't get a lot of useful responses there, so I'm raising the question here...  

Ok, so I'm watching Vaughn Vernon's keynote on http://skillsmatter.com/podcast/agile-testing/vaughn-vernon about actors.
I'm also listening to Rinat Abullin's talk about how actors could be used in beingtheworst on http://beingtheworst.com/2013/episode-29-acting-like-we-get-the-message.

They're talking about how actors (=erlang actors, akka actors. That kind of actors), how actors could be used to make our DDD lifes any easier.

The basic idea I get from all of this is that in the case of 2 aggregates needing to communicate to each other, we could use actors as aggregates and send messages (events & commands) directly to them instead of going through an eventbus/commandbus/application service/event handler/....

I also understand that using actors can be seen as a better way of doing OO because you're forced to use messages for communication. 

So how would that look like using a DDD approach? 

Is every aggregate an actor and are all actors loaded in memory? If they are, I assume they would be held in memory without any state. Otherwise you would need something like coherence or another data fabric to distribute your memory over different nodes, just to keep all your aggregates in memory. Do they load and persist their own state like in the days when it was OK for aggregates to have their own repository injected? Or is the actor a wrapper around the aggregate that takes over the role the application service used to have (=handle security, transaction mgmt, loading and persisting aggregates)?

Or is the value in using actors not in using them as aggregates, but rather as infrastructure and application/domain service components. For example as an implementation of some of the EAI patterns like shown in the blogs on http://vaughnvernon.co/ ?

How would actors fit in? Any ideas?

Best regards
Jan

Bennie Kloosteman

unread,
Sep 29, 2013, 12:17:04 AM9/29/13
to ddd...@googlegroups.com
Technically actors are message pumped sub processes ( normally with a single thread)  with their own memory.  They were originally used so apps can be autonomous ( eg restarted , independent)  and are used as a concurrency mechanism .  Actors do not say anything about OO or people talk to account etc. 

When related to the DDD the granularity is where it gets tricky .

Firstly  larger scale ,   1 Actor = 1 bounded context .. you have a standard Actor message pump processing commands.   This works well and is in fact how some ( many ?)  CQRS systems are implement - ie they are Actor systems  in terms of concurrency. And the fact the system is consistent within the context fits well. 

Now we want to make  1Aggregate an Actor.  Aggregates in CQRS are typically written this way with internal state triggered by commands which create outgoing events . However I would say  this is not efficient , since creating a thread / sub process and message pump (with message queue) for each aggregate is too expensive ..Think 10K - 100K aggregates in memory ( what happens when the queue is full or if expanding how to you handle reader and writer on diff. threads without introducing lots of contentions / spinning and costs from grabbing locks .. )  . You may be able to schedule multiple Actors on a thread  but its a tricky slope.

What is probably better is have all aggregates of 1 type be an Actor . So the fascade for the actor is the event handler , this is doable but you need to manage the cross aggregate consistancy eg Order and Customer are running on different threads and messages may come out of order which can lead to tricky situations in unrolling errors etc .

Also im not sure what you achieve by having 2 aggregates talk to each other .  You still need to load the aggregates  , wire them together and unload them so you need the command handler.  All your doing is removing  the seperation of concerns which you get in normal systems. eg even without actors in cqrs you can do this  ( if you really want) 

LoadAgg1
LoadAgg2
Hook Agg2 to events of Agg1 ( via event bus or direct)
send command to agg 1
Agg2 gets the events and uses them.
Save Agg1 
Save Agg2 
unhook events 

but most systems i have seen get a seperate process to  hook  the event , create the appropriate commands if needed and dont get the Aggregate to listen to events.  Sure this is a bit of trivial code but it keeps things ordered , simple  and avoids some tricky problems. 

Its also worth noting that the LMAX people wrote a system ( with event sourcing ) with Actors  to try to get extreme performance. However they found fewer message pumps worked better    not just for performance ( they found the amount of losses due to context switches and contention was massive) but also ease of programming ( since its sequential and only 1 command is processed at a time , they could write simpler collections )  .. the only catch is all IO is done out of the system on other threads.  1 way to do this in CQRS is  when an event handler handles a command it tells the Data system to load the data and when you have it  enqueue the data as a normal command  which then gets processed when it is its turn. ( With no context switches  or contention most commands take less than a micro second) . 

Ben Kloosterman




--
You received this message because you are subscribed to the Google Groups "DDD/CQRS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Tom Janssens

unread,
Sep 29, 2013, 3:32:14 AM9/29/13
to ddd...@googlegroups.com
What is nice about actors is that it mimics communication between persons in real life, so it sometimes makes it easier to model your domain using this approach. Harder things like eventual consistency etc are easy using actors, as you only have a mailbox to communicate.

In a way actors are an OO approach to software architecture: polymorphism, isolation, encapsulation and messaging are all baked in by definition.

As Alan Kay pointed out, OO was much more about messaging then about objects, and somehow that cornerstone got lost during the years after the initial conception.

About the instance/aggregate: that can/is usually the easiest way to implement it, and it works quite well. A typical example that should give you an idea of how to use actors (in Erlang or Elixir), would be to have one instance per client session for a web server, the guys from whatsapp even have a POC that allows 2 million concurrent client connections communicating over websockets on a single machine.

So, one actor/aggregate would work out just fine in Erlang IMO; you can always load and unload instances if you are running into memory problems.

But, please do note that the Erlang VM is optimized for a lot of small concurrent soft-realtime processes; it has things like local garbage collection, small (200-word-size) overhead/process, and lots of other optimizations.
Also, there is a framework available in Erlang that is like a higher-level library for actors, which allows you to setup FSM's, Servers, Supervisors, Event Servers etc...
Without these libraries - which have multiple decades of man-hours in it -, the actor model kind of works, but it is not truly as elegant and resistant to failures as other actor implementations.

One of the key features actors implementations seem to miss in non-erlang systems, is the whole supervision thing; in Erlang, you typically start out architecting your application by posing the question: "How do I want my app to crash?". If an instance crashes, it will be auto-restarted, within reasonable limits you define yourself. This allows you to remove all the cruft like error-checking, validation etc out of your implementation code, and centralize it.

This approach might seem odd to grasp, but once you get it, it seems odd not to have it; this is a bit hard to explain.

Usually combining this approach with things like pattern-matching etc lead to REALLY succinct code which hardly contains any non-relevant domain code at all...

So, TL;DR: yes, use one actor/instance.


Op zondag 29 september 2013 06:17:04 UTC+2 schreef Bennie Kloosteman:

Richard Rodseth

unread,
Sep 29, 2013, 9:41:20 AM9/29/13
to ddd...@googlegroups.com
As far as event sourcing is concerned, you may be interested in the sample application for the "eventsourced" library:

https://github.com/eligosource
https://github.com/eligosource/eventsourced-example

This is in the process of being rolled into Akka itself as "Akka persistence", and I predict this will be a big boost for event sourcing.





--

Greg Young

unread,
Sep 29, 2013, 10:32:40 AM9/29/13
to ddd...@googlegroups.com
There will also very soon be event store support rolled in


On Sunday, September 29, 2013, Richard Rodseth wrote:
As far as event sourcing is concerned, you may be interested in the sample application for the "eventsourced" library:

https://github.com/eligosource
https://github.com/eligosource/eventsourced-example

This is in the process of being rolled into Akka itself as "Akka persistence", and I predict this will be a big boost for event sourcing.





On Sat, Sep 28, 2013 at 1:44 PM, Jan Bols <guter...@gmail.com> wrote:
I'll make a confession: this is a cross post from the yahoo ddd user group. I didn't get a lot of useful responses there, so I'm raising the question here...  

Ok, so I'm watching Vaughn Vernon's keynote on http://skillsmatter.com/podcast/agile-testing/vaughn-vernon about actors.
I'm also listening to Rinat Abullin's talk about how actors could be used in beingtheworst on http://beingtheworst.com/2013/episode-29-acting-like-we-get-the-message.

They're talking about how actors (=erlang actors, akka actors. That kind of actors), how actors could be used to make our DDD lifes any easier.

The basic idea I get from all of this is that in the case of 2 aggregates needing to communicate to each other, we could use actors as aggregates and send messages (events & commands) directly to them instead of going through an eventbus/commandbus/application service/event handler/....

I also understand that using actors can be seen as a better way of doing OO because you're forced to use messages for communication. 

So how would that look like using a DDD approach? 

Is every aggregate an actor and are all actors loaded in memory? If they are, I assume they would be held in memory without any state. Otherwise you would need something like coherence or another data fabric to distribute your memory over different nodes, just to keep all your aggregates in memory. Do they load and persist their own state like in the days when it was OK for aggregates to have their own repository injected? Or is the actor a wrapper around the aggregate that takes over the role the application service used to have (=handle security, transaction mgmt, loading and persisting aggregates)?

Or is the value in using actors not in using them as aggregates, but rather as infrastructure and application/domain service components. For example as an implementation of some of the EAI patterns like shown in the blogs on 


--
Le doute n'est pas une condition agréable, mais la certitude est absurde.

Jan Bols

unread,
Sep 30, 2013, 7:40:40 AM9/30/13
to ddd...@googlegroups.com
But doesn't that imply you would have to keep all your aggregates in memory? How would you do that?

Jan

Op zondag 29 september 2013 09:32:14 UTC+2 schreef Tom Janssens:

Tom Janssens

unread,
Sep 30, 2013, 8:44:34 AM9/30/13
to ddd...@googlegroups.com
Use a recently used list, cap the amount of instances, and persist the state of the ones that get stale (or if you are using ES, you don't even need to do that).
This should be on the infrastructure level, NOT on the actor level IMO

Op maandag 30 september 2013 13:40:40 UTC+2 schreef Jan Bols:

Jan Bols

unread,
Oct 1, 2013, 3:03:39 AM10/1/13
to ddd...@googlegroups.com
Oh, I see,
so using actors doesn't mean you don't need command handlers, event handlers, UOW's, repositories and all that stuff. It just means all communication goes through messaging and all messages end up in some actor's mailbox.

Right?

So when a ChangeAddressCommand is sent to a commandHandler, it reacts by loading a CustomerAggregateActor via some repository, starting some UOW and sending the ChangeAddressCommand to the CustomerAggregateActor 's mailbox. The only diffference with the classical way of doing things is that the aggregate/actor doesn't have any public methods anymore except for the slot in the mailbox. Is that all there is?

Greetgins
Jan



Op maandag 30 september 2013 14:44:34 UTC+2 schreef Tom Janssens:

Greg Young

unread,
Oct 1, 2013, 8:10:37 AM10/1/13
to ddd...@googlegroups.com
A method call equates to a message pass. In many languages it is actually implemented this way (ruby, small talk). The main difference is how concurrency is viewed.
--
You received this message because you are subscribed to the Google Groups "DDD/CQRS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

J Fernandes

unread,
Oct 1, 2013, 8:43:28 AM10/1/13
to ddd...@googlegroups.com
Hi,

Just to double check my understanding, how would this work for inter aggregate root messaging? Following up on the below description, would the handlers have the responsibility to instantiate all the aggregate root actors in the play scene?


"So when a ChangeAddressCommand is sent to a commandHandler, it reacts by loading a CustomerAggregateActor via some repository, starting some UOW and sending the ChangeAddressCommand to the CustomerAggregateActor 's mailbox. The only diffference with the classical way of doing things is that the aggregate/actor doesn't have any public methods anymore except for the slot in the mailbox. Is that all there is?"


Thanks,

J
To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.

Jimmy Bogard

unread,
Oct 2, 2013, 9:38:57 AM10/2/13
to ddd...@googlegroups.com
+1

Does the other aggregate participate in the same transaction or not is a really key point.

I tend to have them NOT participate in the same transaction, as it can be confusing to see them both commit together (not to mention, you likely don't want a bug in the other aggregate's handler to affect YOUR commit).

Tom Janssens

unread,
Oct 3, 2013, 11:19:14 AM10/3/13
to ddd...@googlegroups.com
IMO, but YMMV, actors need a mailbox per process. Actors can only send messages to other processes. Actors process one or more messages at a time from their own mailbox. This is how it should be, consider people at work using only paper, they usually have an inbox, and they can get the messages out of their inbox in the order they want them, a person can put a form in another person's mailbox, but when and how the other person parses it's own mailbox is not relevant to the first person; things are/should be truly isolated!

The only thing one can do, as a form of interaction, is contact a person when you did not get a status report in time in your mailbox (because the other person got fired, or he no longer reports to you).

Having one messagebus is IMO like having one person collecting all the forms and putting them in the inboxes of other persons (either driectly/every week, when a treshold is reached/..). One can see IRL that this is not very good, as this is a SPOC/SPOF. Also, that one person has to know everything about everyone. Just model your systems like you would act IRL with persons, and you will be way better off (f.e. erlang supervisors are allowed to replace a person/group/division and replace it with others if they do not suffice).

Op dinsdag 1 oktober 2013 09:03:39 UTC+2 schreef Jan Bols:

Jan Bols

unread,
Oct 4, 2013, 7:03:08 AM10/4/13
to ddd...@googlegroups.com
Hi Tom,

I understand the analogy with people having an inbox/mailbox, communicating with others through messages. I also can imagine that using actors solve some concurrency issues you might have in highly collaborative environments. Finally I can see where a supervisor mechanism can do some powerful things in a distributed application when things go wrong. 

But... would it be fair to say that most business problems shouldn't be solved using actors? I mean, is it only the highly concurrent/distributed DDD applications that benefit from using actors.
Or does the "actors are a better OO approach" make you want to use actors by default in a DDD project?

Jan

Tom Janssens

unread,
Oct 4, 2013, 11:07:01 PM10/4/13
to ddd...@googlegroups.com
I would say it depends ;) But overall I think the CQRS architecture somewhat mimics the actor model, so one might as well reap the full benefits of it.

Op vrijdag 4 oktober 2013 13:03:08 UTC+2 schreef Jan Bols:

Bennie Kloosteman

unread,
Oct 4, 2013, 11:24:01 PM10/4/13
to ddd...@googlegroups.com
Agree , 

but the Granularity is crucial  Actor can be  Aggregate , Aggregate Type , Bounded Context.  I see no practical reason to go down to Aggregate . The others are much better from an infra structure point of view.

Ben

Tom Janssens

unread,
Oct 5, 2013, 2:28:40 AM10/5/13
to ddd...@googlegroups.com
It makes sense to put it on the lowest level to keep things simple, however, your infrastructure has to allow this. In Erlang this is easy, but using an eventbus or similar, I can imagine this is harder. YMMV.

Op zaterdag 5 oktober 2013 05:24:01 UTC+2 schreef Bennie Kloosteman:

Bennie Kloosteman

unread,
Oct 5, 2013, 8:33:09 AM10/5/13
to ddd...@googlegroups.com
Agree on Erlang  ( or similar runtime) or where you have a low aggregate count , certainly not for high agg counts and most C#/ Java  runtimes. 

Ben


--
Reply all
Reply to author
Forward
0 new messages