1

我开始使用 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

但是,我的两种状态accumulatingemitting不得不处理彼此的命令。我可以使用.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意识到我真正需要的是一种将 a 定义Behavior为的方法

def receiveMessage[T, V <: T](handler: V => Behavior[T]): Behavior[T] = ???

wherehandler可以让我对窄类型进行详尽的检查,V并且任何消息TV将返回Behaviors.unhandled。我似乎无法让这些类型工作以实现这样的功能。

4

1 回答 1

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
于 2019-05-27T13:50:43.723 回答