如何提取所有持久化实体



我对 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));
};
}

现在,我不是使用给定的 ID 查找实体,而是想获取所有实体,例如persistentEntityRegistry.getIds()之类的实体,然后我可以按 id 逐个获取它们。但是,实体注册表似乎不存在这种方法?

可以通过直接使用底层 Akka 持久性框架来获取所有实体 ID 来执行allPersistenceIdscurrentPersistenceIds查询

您可以在 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);
}
//...
}

这种方法虽然可行,但很少是一个好主意。您可能已经注意到示例代码中的注释:"这不应该用于生产"。无法使用此方法执行聚合命令:您只能逐个向每个实体发送命令。这可能会导致服务群集中节点之间的内存消耗和流量激增。也无法按实体状态的任何条件筛选此 ID 列表,因为你可能习惯于使用面向行的 SQL 数据模型。

为数据定义读取端模型几乎总是更合适。这采用单独的"读取端"数据存储的形式,该数据存储专为应用程序所需的查询类型而构建,以及一个事件处理器,该事件处理器在实体发出事件时自动调用,该处理器更新读取端数据存储以反映这些更改。

Lagom 框架通过管理读取端事件处理器、跟踪它们在事件日志中的位置以及在重新启动或失败时自动重新启动它们,帮助确保应用程序中的最终一致性。否则,对于聚合操作,很难实现这种类型的复原能力。

(这个答案改编自Lagom框架谷歌小组中的相关讨论。

最新更新