我开始与Akka Typed合作以对我的行为进行详尽的模式匹配,这对于每个演员的外在契约都非常有用。但是,如果参与者是状态机,则不同的状态很可能具有状态特定的命令。
我可以将状态特定的命令隐藏为整个命令的私有成员,如下所示:
sealed trait Command
final case class Add(id: Int) extends Command
private final case object AccumulationTimeout extends Command
private final case object Ack extends Command
但是,我的两个状态accumulating
和emitting
必须处理彼此的命令。我可以使用.receivePartial
或全部包含
case _ => Behaviors.unhandled
在两种情况下,我都失去了详尽的模式匹配,以确保我能正确处理状态。
我可以进一步完善命令,例如:
sealed trait Command
sealed trait Accumulating extends Command
private final case object AccumulationTimeout extends Accumulating
sealed trait Emitting extends Command
private final case object Ack extends Emitting
final case class Add(id: Int) extends Accumulating with Emitting
这样,我可以定义Behavior[Accumulating]
和Behavior[Emitting]
两者均为Behavior[Command]
,但是要注意的是,由于这两种行为都无法转换为另一种行为必须返回自己的类型。
我尝试了.widen
和.narrow
的各种排列,但无济于事,意识到我真正需要的是一种将Behavior
定义为的方式
def receiveMessage[T, V <: T](handler: V => Behavior[T]): Behavior[T] = ???
其中handler
将对窄型V
进行详尽检查,对于T
之外的任何消息V
都将返回Behaviors.unhandled
。我只是似乎无法使类型起作用以实现这样的功能。
答案 0 :(得分:0)
一个想法是对特定于状态的命令子集进行初始匹配。像这样:
def accumulating: Behavior[Command] =
Behaviors.receive {
case acc: Accumulating =>
acc match {
//... complete for the message subtype or compiler fails...
}
case _ =>
// other state subtypes are
Behaviors.unhandled