我对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一个接一个地获取它们。但是,实体注册表似乎不存在这样的方法吗?
答案 0 :(得分:2)
可以通过使用底层的Akka Persistence框架直接获取所有实体ID来执行allPersistenceIds
or currentPersistenceIds
query
您可以在UserServiceImpl.java
中的Lagom在线拍卖示例应用程序中查看此示例:
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数据模型。
为您的数据定义read-side model几乎总是更合适。这采用单独的“读取端”数据存储的形式,该存储是为了满足应用程序所需的查询类型而构建的,以及在实体发出事件时自动调用的事件处理器,它会更新读取端数据存储反映这些变化。
Lagom框架通过管理读取端事件处理器,跟踪它们在事件日志中的位置以及在重新启动或失败时自动重新启动它们,有助于确保应用程序的最终一致性。对于集合操作来说,这种类型的弹性是非常棘手的。
(此答案改编自related discussion in the Lagom Framework Google Group。)