Как получить все сохраненные объекты
Я совершенно новичок в фреймворке lagom, поэтому сегодня я читал документацию и начал модифицировать их пример с hello world.
Тем не менее, я не могу найти способ получить все сохраненные сущности (т.е. все постоянные приветствия в этом примере).
Вот как пример по умолчанию выбирает приветствие человека:
@Override
public ServiceCall<GreetingMessage, Done> useGreeting(String id) {
return request -> {
// Look up the hello world entity for the given ID.
PersistentEntityRef<HelloCommand> ref = persistentEntityRegistry.refFor(HelloWorld.class, id);
// Tell the entity to use the greeting message specified.
return ref.ask(new UseGreetingMessage(request.message));
};
}
Теперь, вместо того, чтобы искать сущность, используя заданный идентификатор, я хочу получить все сущности, например что-то вроде persistentEntityRegistry.getIds()
Тогда я мог бы получить их один за другим. Тем не менее, кажется, что такой метод не существует для реестра сущностей?
1 ответ
Можно получить все идентификаторы сущностей, используя базовую структуру Akka Persistence для выполнения allPersistenceIds
или же currentPersistenceIds
запрос
Вы можете увидеть пример этого в приложении примера аукциона Lagom, в UserServiceImpl.java
:
public class UserServiceImpl implements UserService {
//...
private final CurrentPersistenceIdsQuery currentIdsQuery;
private final Materializer mat;
@Inject
public UserServiceImpl(PersistentEntityRegistry registry, ActorSystem system, Materializer mat) {
//...
this.mat = mat;
this.currentIdsQuery =
PersistenceQuery.get(system)
.getReadJournalFor(
CassandraReadJournal.class,
CassandraReadJournal.Identifier()
);
//...
}
//...
@Override
public ServiceCall<NotUsed, PSequence<User>> getUsers() {
// Note this should never make production....
return req -> currentIdsQuery.currentPersistenceIds()
.filter(id -> id.startsWith("UserEntity"))
.mapAsync(4, id ->
entityRef(id.substring(10))
.ask(UserCommand.GetUser.INSTANCE))
.filter(Optional::isPresent)
.map(Optional::get)
.runWith(Sink.seq(), mat)
.thenApply(TreePVector::from);
}
//...
}
Такой подход, хотя и возможен, редко бывает хорошей идеей. Вы, возможно, заметили комментарий в примере кода: "это никогда не должно создавать". При таком подходе невозможно выполнить агрегирование команд: вы ограничены отправкой команд каждой сущности одна за другой. Это может привести к скачкам потребления памяти и трафика между узлами в кластере служб. Также невозможно отфильтровать этот список идентификаторов по каким-либо критериям состояния объекта, как вы могли бы использовать для ориентированных на строки моделей данных SQL.
Почти всегда более уместно определить модель чтения для ваших данных. Это принимает форму отдельного хранилища данных "на стороне чтения", созданного специально для того типа запросов, который требуется вашему приложению, и обработчика событий, который автоматически вызывается, когда ваши объекты генерируют события, что обновляет хранилище данных на стороне чтения. чтобы отразить эти изменения.
Инфраструктура Lagom помогает обеспечить возможную согласованность в вашем приложении, управляя обработчиками событий на стороне чтения, отслеживая их положение в журнале событий и автоматически перезапуская их при перезапуске или сбое. Этот тип устойчивости сложно реализовать для агрегатных операций.
(Этот ответ взят из соответствующего обсуждения в Группе Google Lagom Framework.)