【发布时间】:2017-07-26 17:54:28
【问题描述】:
我尝试使用akka 和futures 来理解故障处理。
例如,我有父母和孩子演员。
子actor有两种失败案例:
案例 1) 消息处理时发生错误
案例 2) 未来发生错误
在这两种情况下,我都需要将错误传播给父级,但在第二种情况下,它不会发生。我做错了什么?
import akka.actor.SupervisorStrategy.{Decider, Stop}
import akka.actor.{Actor, ActorRef, ActorSystem, OneForOneStrategy, Props, SupervisorStrategy}
import akka.testkit.{TestKit, TestProbe}
import org.junit.{After, Before, Test}
import scala.concurrent.Future
import scala.util.{Failure, Success}
class Parent(_case: String, probe: ActorRef) extends Actor {
val child = context.actorOf(Props(new Child(_case)), "myLittleChild")
final val defaultStrategy: SupervisorStrategy = {
def defaultDecider: Decider = {
case ex: Exception =>
probe ! ex
Stop
}
OneForOneStrategy()(defaultDecider)
}
override def supervisorStrategy: SupervisorStrategy = defaultStrategy
override def receive: Receive = {
case msg => unhandled(msg)
}
}
class Child(_case: String) extends Actor {
implicit val ec = context.dispatcher
override def preStart(): Unit = {
self ! _case
}
override def receive: Receive = {
case "case1" => throw new RuntimeException("fail")
case "case2" => Future[String] {
throw new RuntimeException("fail")
}.onComplete {
case Success(s) => println(s)
case Failure(e) =>
throw e
}
case msg => unhandled(msg)
}
}
class TestExample {
protected implicit var system: ActorSystem = _
@Before
def setup(): Unit = {
system = ActorSystem.create("test")
}
@After
def tearDown(): Unit = {
TestKit.shutdownActorSystem(system)
}
@Test
def case1(): Unit = {
val testProbe = TestProbe()
system.actorOf(Props(new Parent("case1", testProbe.ref)))
testProbe expectMsgClass classOf[RuntimeException]
}
@Test
def case2(): Unit = {
val testProbe = TestProbe()
system.actorOf(Props(new Parent("case2", testProbe.ref)))
testProbe expectMsgClass classOf[RuntimeException]
}
}
【问题讨论】: