Могу ли я читать / писать от отдельных актеров с одинаковым PersistenceId?
Вступление Akka.Persistence в блоге Petabridge проясняет, что у вас не может быть нескольких актеров с одинаковым PersistenceId:
PersistenceId
поле имеет важное значение - оно однозначно идентифицирует сущность, которая сохраняет свое состояние, используя Akka.Persistence, и в каждый момент времени должен быть ровно один постоянный субъект для одногоPersistenceId
,[...] так что представьте, если у вас есть два актера с одинаковым PersistenceId, но разными порядковыми номерами, пишущими в один и тот же магазин. Это будет хаос и неизбежно приведет к ошибке - поэтому очень важно, чтобы каждый PersistenceId был глобально уникальным в вашей ActorSystem (по крайней мере для всех актеров, пишущих в этот магазин).
Я могу придумать сценарий, в котором у вас будет два отдельных участника: один, который заботится о сохранении постоянного состояния в базу данных (т.е. вызовы Persist()
) и еще один, который воспроизводит сообщения из журнала при запросе вручную (например, звонки Recover()
). Операции чтения и записи будут происходить от разных субъектов. Только один когда-либо пишет, и только один когда-либо читает. Тем не менее, оба нуждаются в одинаковом постоянстве.
Я считаю, что в этом сценарии должно быть безопасно, чтобы два актера использовали один и тот же PersistenceId. Но, учитывая приведенные выше предупреждения, есть ли какая-то причина, почему такой подход может быть опасным на практике?
2 ответа
Я могу вспомнить сценарий, в котором у вас будет два отдельных участника: один, который заботится о сохранении состояния постоянства в базе данных (т.е. вызывает Persist()), и другой, который воспроизводит сообщения из журнала, когда запрашивается это вручную (т.е. вызывает Восстановление ()). Операции чтения и записи будут происходить от разных субъектов. Только один когда-либо пишет, и только один когда-либо читает. Тем не менее, оба нуждаются в одинаковом постоянстве.
Требуемое поведение уже выставлено как Постоянные субъекты и Постоянные представления. Из документов:
Хотя постоянный субъект может использоваться для создания и сохранения событий, представления используются только для чтения внутреннего состояния на их основе. Подобно персистентному действующему субъекту, представление имеет PersistenceId, чтобы указать коллекцию событий, которые необходимо повторно отправить в текущее представление. Однако это значение должно коррелироваться с PersistentId актера, который является источником событий.
Изменить: обновлено, чтобы предоставить больше информации о том, как получить доступ к событиям в постоянном представлении.
Вы можете загрузить из журнала, переопределив Receive
метод Persistent View
, Аргументом для этого метода является объект, поэтому вам нужно привести этот объект к любому событию (событиям), которое вы сохранили через Persistent Actor
,
Receive
Метод также обрабатывает любые другие сообщения, которые вы передаете в представление - например, запрос на чтение из уровня представления. Обычно я храню список событий внутри представления и возвращаю из них пользовательскую модель представления.
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;
}
Поскольку 2016 год сейчас 5 лет назад, PersistenceView устарели. В настоящее время используется PersistenceQuery .