I'm new to Akka.NET (and Actors in general) and have some questions regarding event sourcing and CQRS in Akka.NET
Lets say for example that I have an Orders bounded context (as in Orders in an online store)
class OrdersAggregate
{
public OrdersAggregate()
{
Command<NewOrder>(o => HandleNewOrder(o));
}
void HandleNewOrder(NewOrder o)
{
Persist(o, e =>
{
// update state
});
}
}
What would be the best way to implement a read store(s) around these orders (for example, having a dedicated read store for the UI)?
I see that it's possible to send events after a command was persisted, like this
Persist(o, e =>
{
// update state
Context.System.EventStream.Publish(e);
});
Then I could just subscribe to that message and pipe it into an actor that's responsible for storing the messages in a database that would serve as my read store, but it looks like this approach is error prone since there is no way to guarantee that the event publishing won't fail. (normally, without Akka, I would use something like the outbox pattern to ensure that persistence and event delivery happen in a transaction).
So is this a good way of sending events to build a read store or is there a better way to do it?
My second question is very similar. What is the best pattern for sending cross domain events (across bounded contexts) in Akka.NET?
For example, I want to subscribe to NewOrderCreated
events from the warehouse bounded context
It looks like using the Context.System.EventStream.Publish
would suffer from the same problems I've just described.
Akka.Persistence.Query is the right tool for implementing CQRS on top of Akka.Peristence. This allows you to periodically read in events from an Akka.Persistence journal after they've been committed and can be used to create projections and materialized views.
You can see a large-scale example I implemented using Akka.Persistence.Query and Akka.Cluster here: https://github.com/Aaronontheweb/InMemoryCQRSReplication