Отправка обратно отправителю от супервизора в случае сбоя
У меня есть актер, который выступает в роли супервизора, но также должен "возвращать" данные вызывающей стороне, независимо от того, актер это или нет, это не должно иметь значения.
Я прошу моего руководителя, давайте назовем его SV.
SV обрабатывает сообщение, которое я ему отправляю, и отправляет ответ.
val system = ActorSystem("ActorSystem")
val sv = system.actorOf(Props[SV], name = "SV")
sv ? msg
И метод получения SV выглядит так:
def receive = {
case msg => (someChild ? msg).pipeTo(sender)
...
}
Это все работает отлично. Проблема в том, что когда ребенок выдает исключение, это исключение отлавливается стратегией супервизора.
override def supervisorStrategy = OneForOneStrategy () {
case e : Throwable => {
val newResponse = someNewResponse
sender ! newResponse
...
}
}
Отправитель больше не является ссылкой на того, кто вначале вызывал SV, и я не могу понять, как отправить сообщение обратно к аске и вернуться к исходному потоку.
2 ответа
Используете ли вы стратегию супервизора и исключения для управления потоком или вашими данными? Рассмотрите возможность использования системы типов (Option
типа или Failure
на ответ Future
) для случаев "исключений" в ваших дочерних субъектах и обрабатывать поток ответов без исключений.
Стратегия супервизора предназначена для необработанных исключений. При возникновении необработанного исключения вы теряете возможность ответить отправителем сообщением. Если вы не заключите отправителя в необработанное исключение, как предлагает Роланд Кун.
Позвольте стратегии супервизора вместо этого управлять тем, как система актера должна реагировать на ваши необработанные исключения, сопоставляя их с Directive
,
Одно из трех правил Actor: "Actor может отправлять конечное число сообщений другим Actor, которых он знает". Здесь важны два последних слова: если супервизор не был каким-либо образом представлен первоначальному отправителю и произошел сбой (исключение) сама по себе также не содержит ссылку на отправителя, тогда руководитель не может отправить сообщение отправителю. Либо вы перехватываете все исключения в дочернем актере, оборачиваете их вместе с отправителем в свой собственный тип исключения и затем отбрасываете, либо исходное сообщение должно пройти через супервизора к ребенку и обратно, чтобы супервизор мог видеть, что ответ является выдающимся, когда происходит сбой.