Can I Read/Write from separate actors with same PersistenceId?

馋奶兔 提交于 2020-01-07 03:40:29

问题


The Petabridge blog's Akka.Persistence intro makes it clear that you can't have multiple actors with the same PersistenceId:

The PersistenceId field is important - it uniquely identifies an entity that is persisting its state using Akka.Persistence, and there should be exactly one persistent actor at any given time for a single PersistenceId.

[...] so imagine if you have two actors with the same PersistenceId but different sequence numbers writing to the same store. It will be chaos and will inevitably error out - so that’s why it’s crucial that every PersistenceId be globally unique within your ActorSystem (at least for all actors writing to that store.)

I can think of a scenario where you would have two separate actors: one that takes care of saving persistence state to database (i.e. calls Persist()), and another one that replays messages from the journal when manually requested to do so (i.e. calls Recover()). The read and write operations would occur from different actors. Only one ever writes, and only one ever reads. However, both need the same PersistenceId.

I believe that in this scenario it should be safe to have two actors using the same PersistenceId. But given the above warnings quoted above, is there any reason why such an approach could be dangerous in practice?


回答1:


I can think of a scenario where you would have two separate actors: one that takes care of saving persistence state to database (i.e. calls Persist()), and another one that replays messages from the journal when manually requested to do so (i.e. calls Recover()). The read and write operations would occur from different actors. Only one ever writes, and only one ever reads. However, both need the same PersistenceId.

The behaviour you require is already exposed as Persistent Actors and Persistent Views. From the docs:

While a persistent actor may be used to produce and persist events, views are used only to read internal state based on them. Like the persistent actor, a view has a PersistenceId to specify a collection of events to be resent to current view. This value should however be correlated with the PersistentId of an actor who is the producer of the events.

Edit: updated to provide more info on how to access events in the Persistent View.

You can load from a journal by overriding the Receive method of a Persistent View. The argument for this method is an object, so you'll need to cast that object to whatever event(s) you have persisted via the Persistent Actor.

The Receive method also handles any other messages you pass to the View - e.g. a read request from the presentation layer. I usually store a list of events internally in the View and return a custom view model from these.

protected override bool Receive(object message)
{
    // if the message is a previously persisted event, update our internal list
    var e = message as MyEvent;
    if (e != null) _events.Add(e);
    return true;

    // if the message is a request for a view model, read from our list of stored events
    var r = message as ReadRequest;
    if (r == null) return false;
    Sender.Tell(new ViewModel(_events));
    return true;
}


来源:https://stackoverflow.com/questions/39210277/can-i-read-write-from-separate-actors-with-same-persistenceid

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!