Я начал работать с 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
. Я просто не могу заставить работать типы для реализации такой функции.