【发布时间】:2020-09-11 08:30:33
【问题描述】:
我在演员模型中的关系中挣扎。让我用一个简单的例子。系统中有两种参与者类型:仓库和项目。物料总是分配给特定的仓库。 AddStock 命令允许增加分配给给定仓库位置的库存数量。只有仓库知道自己的位置,因此项目必须询问其仓库该位置是否有效以执行自己的业务逻辑。我已经想到了一些解决方案
- AddStock 命令包含仓库分片区域的 ActorRef,它允许 Item 向 Warehouse 询问位置。
- 以某种方式仅允许仓库发出命令 AddStock,该命令允许预先验证位置。不知道如何实现这一点,我考虑过私人命令或一些识别过程
我不喜欢这两种解决方案。它为简单的任务增加了许多不必要的复杂性。我认为这里的 OOP 思维可能存在问题,分布式 Actor 世界受其自身规则的约束。
在我的场景中,我将 Item 和 Warehouse 视为单独的集合。它们都被实现为 Persistent Actor(使用集群分片)。
只要您假设只有 Warehouse 可以调用 Item::AddStock,一切都很容易。然后 Warehouse 只是在调用之前验证位置。但是可以直接调用 Item 并跳过所有验证。项目无法知道是否是正确的仓库发出了呼叫。在纯 OOP/DDD 方法中很容易实现。项目知道仓库 ID,更改数量看起来像这样
item.addStock("L2", 100, warehouse)
知道仓库 ID 的项目可以验证提供的仓库是否是仓库。并且有仓库可能会询问位置是否有效。我当前的项目处理程序实现:
case AddStock(region, location, quantity) => {
region ? EntityEnvelope(warehouseId, HasLocation(location)) map (
_ => VerifiedAddStock(quantity)
) pipeTo self
VerifiedAddStock 是 Item 的私有对象,所以我确定谁是命令发出者(几乎是因为它不强制标识)。
那么问题是如何在 Actor 世界中建模这种关系?绕过shard region ref是常态吗?
有人可能会认为这是由于聚合/参与者边界不当造成的设计缺陷本身,但这只是一个示例。
【问题讨论】:
标签: java scala concurrency akka actor