Отправка обратно отправителю, от супервайзера, в случае сбоя

У меня есть актер, который действует как супервизор, но также должен «возвращать» данные вызывающей стороне, независимо от того, является ли это актером или нет, это не имеет значения.

Я прошу своего Супервайзера, назовем его С.В.

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, и я, похоже, не могу понять, как отправить сообщение обратно запрашиваемому и вернуться к моему исходному потоку.


person Kao    schedule 08.12.2015    source источник


Ответы (2)


Используете ли вы стратегию супервизора и исключения для управления потоком или вашими данными? Рассмотрите возможность использования системы типов (тип Option или Failure в ответе Future) для случаев «исключения» в ваших дочерних субъектах и ​​обрабатывайте поток ответов без исключений.

Стратегия супервизора предназначена для необработанных исключений. Когда возникает необработанное исключение, вы теряете возможность ответить отправителю сообщением. Если вы не завернете отправителя в необработанное исключение, как предлагает Роланд Кун.

Вместо этого позвольте стратегии супервизора управлять тем, как система субъектов должна реагировать на ваши необработанные исключения, сопоставляя их с Directive.

person doorstuck    schedule 09.12.2015

Одно из трех правил Актера гласит: «Актор может отправлять конечное число сообщений другим Актерам, которых он знает». Последние два слова здесь критичны: если супервизор каким-то образом не был представлен исходному отправителю и сам отказ (исключение) также не содержит ссылки на отправителя, то супервизор не может отправить сообщение отправителю. Либо вы перехватываете все исключения в дочернем акторе, заключаете их вместе с отправителем в свой собственный тип исключения, а затем повторно создаете, либо исходное сообщение должно проходить через супервизора к дочернему субъекту и обратно, чтобы супервизор мог видеть, что ответ является выдающимся, когда происходит сбой.

person Roland Kuhn    schedule 09.12.2015
comment
Я не уверен, что понимаю, исходное сообщение должно проходить через супервизора к ребенку и обратно, разве это не то, что я делаю, когда я ask ребенок, от супервизора? Однако он никогда не возвращается прямо туда, где я спросил, потому что происходит исключение, поэтому вместо этого срабатывает SupervisorStrategy. Отсюда я теперь хочу отправить сообщение обратно исходному отправителю (от руководителя) с другим ответом. Если я все еще недостаточно ясен в своем вопросе, я могу обновить его с помощью блок-схемы, если это необходимо. - person Kao; 09.12.2015
comment
Ах да, я не правильно разобрал использование ask; да, это то, что я имел в виду. Тогда вам все равно нужно будет зафиксировать исходный sender в супервизоре при формулировании supervisorStrategy, что означает управление количеством невыполненных запросов (чтобы не запутаться). - person Roland Kuhn; 09.12.2015