У меня есть API, который создает актер A (во время выполнения).Затем A создает Actor B (также во время выполнения).
У меня есть другой API, который создает Actor C (отличается от Actor, код команды между ними отсутствует), а C создает Actor D.
Я хочу аккуратно отключить A и C, как только B и D закончили обработку своих сообщений (A и C не обязательно работают вместе, они не связаны).
Отправка таблеток с отравлением в A / C не достаточно хороша, потому чтодети (B / D) все равно получат остановку контекста и не смогут завершить свои задачи.
Я понимаю, что мне нужно реализовать новый тип сообщения.Я не понимал, как создать инфраструктуру, чтобы и A, и C знали, как реагировать на это сообщение, не имея одинакового метода получения дубликатов в обоих.
Решение, которое я нашел, заключалось в создании новой черты, которая расширяетАктер и переопределить необработанный метод.Код выглядит следующим образом:
object SuicideActor {
case class PleaseKillYourself()
case class IKilledMyself()
}
trait SuicideActor extends Actor {
override def unhandled(message: Any): Unit = message match {
case PleaseKillYourself =>
Logger.debug(s"Actor ${self.path} received PleaseKillYourself - stopping children and aborting...")
val livingChildren = context.children.size
if (livingChildren == 0) {
endLife()
} else {
context.children.foreach(_ ! PleaseKillYourself)
context become waitForChildren(livingChildren)
}
case _ => super.unhandled(message)
}
protected[crystalball] def waitForChildren(livingChildren: Int): Receive = {
case IKilledMyself =>
val remaining = livingChildren - 1
if (remaining == 0) { endLife() }
else { context become waitForChildren(remaining) }
}
private def endLife(): Unit = {
context.parent ! IKilledMyself
context stop self
}
}
Но это звучит немного странно ... Есть ли лучшее (не хакерское) решение?