我试图弄清楚如何使用持久性actor来模拟远程“IoT”设备的状态,例如:
用户想打开灯,这样我们才能做到最合乎逻辑 .
-
用户发送
OnCommand
-
持久化actor接收命令,生成
LightTurnedOnEvent
并将其状态更新为on
所以这是有道理的,但这里的问题是灯光实际上从未打开过 . 好的,那么我们 Build 一个知道低级硬件控制伏都教的 LightControlActor
. 这个演员倾听 LightTurnedOnEvent
,当它得到它时,它会做到这一点并且在光线上转动 .
Awsome现在我们开灯了!但不开心 . LightTurnedOnEvent
有点躺在这里,光还没有打开 . 遵循这个逻辑 LightTurnedOnEvent
应该由 LightControlActor
生成,我的持久化演员应该生成一些 SentRequestToTurnOnLight
但现在这对我来说变得复杂,具有所有不同的语义 .
-
用户发送
OnCommand
-
持久性actor recivecs
OnCommand
generateRequestedLightTurnOnEvent
并将状态设置为pending . -
LightController拾取
RequestedLightTurnOnEvent
并尝试打开外部系统上的指示灯 .
那么什么呢?现在我如何更新持久化演员的状态?让LightController发送一些veird命令 SetStateToOnCommand
?
那么当实际打开灯时,如何更新持久状态?
2 回答
一个想法是为你的活动选择类似“saga”的东西 .
这为您提供了精细的控制 . 如果发生碰撞并且在恢复过程中,您可以检查灯是否已打开或
LightController
是否处于暂挂状态 . 如果它处于暂挂状态,您可以重新发送LightTurnOnCommand
.但即使硬件控制器这么说,你也永远不知道灯亮了,即灯泡可能会损坏 .
事件的想法是它们在有限的背景下的含义 . 在您的情况下,
LightTurnedOnEvent
由持久性actor拥有,并且仅在其上下文中具有严格意义 . 从业主演员的POV开始,灯应该亮,未来TurnOnCommand
不会改变这个状态,不会发出新事件(它是幂等的) .如果您希望此事件具有其他含义,则需要一个对此事件作出反应的Saga(或任何您想要调用的事件),并在另一个上下文中(即在HW上下文中)将另一个命令发送给另一个actor . 这个HW演员将发出自己的事件,仅在其上下文中相关,即
LightBulbCoupledToPowerSource
或类似的东西;它甚至可以像另一个一样命名为LightTurnedOnEvent
,但在一个单独的命名空间中,很可能与其他属性一样 .为了更好地看到这种关注/背景的分离,我们可以想象一种情况,其中一个Saga,例如,响应于
LightTurnedOnEvent
将向3个不同的灯泡发送3个命令 .