12 May 2014

More on CQRS and Actors

So today, I discovered the Orleans project. I also watched the excellent presentation on it from Build 2014. The actor model has a lot of appeal for easier creation of scalable, distributed systems. In trying to work out how it would resolve with a DDD/CQRS system, I came up with some observations.

In the Build example, the presenter listed statistics as an actor (aka "grain"). As described, this report-type actor would have the same downsides as a report from an N-tier system. In other words, their described system did not have the hallmark separation between reads and writes of a CQRS system. The report data updates are destructive, history is lost, and the reports can't be proven correct (replayed).
If doing actors in a CQRS system, the actors would only be used on the write side. Using event sourcing as the actor persistence mechanism, denormalizers would still come into play for the read side, not actors.

Actors seems to fit really well for aggregates, but what about Process Managers or Sagas? These are a harder fit because they are not necessarily explicitly called by a user or another actor. They are created and run as a result of events in the system. They are system automations, if you will. The best way that I can think of to implement these event-driven components as actors is to have a separate event listener that forwards the appropriate events to them.

To my thinking, the main purpose of actors in a DDD/CQRS system is to give aggregates (and maybe process managers) a structure that can be interacted with for computation. Ideally, the actor subsystem comes with the necessary architecture to abstract away technical concerns such as message dispatch, scale, distribution, etc. The Orleans project seems to provide a lot of that and apparently does it pretty well for the Halo 4 team.

The main thing that I find really weird about it is their "message passing" method. I like to store the commands I send to the system as well as the events they produce for traceability. Orleans doesn't allow this because it hides the message passing from you. Instead, you load a faux actor and call a proxy method on it. The system takes care of serializing your method call with parameters and delivering that message to the real actor on the server.

I'm eager to see what comes of Orleans. I hope Microsoft decides to bring it out of research and turns it into a proper product. It has the potential for great things in the DDD/CQRS space.