pekko/akka-docs/rst/scala/code/docs/actor/FaultHandlingDocSpec.scala
Patrik Nordwall ef387af2fc =doc #16910 Fix include sections in fault tolerance docs
* and don't show AkkaSpec in doc code

(cherry picked from commit 23be60395cdea846ef168960cd05e88c6bd29556)

Conflicts:
	akka-docs/rst/scala/code/docs/actor/FaultHandlingDocSpec.scala
	akka-docs/rst/scala/fault-tolerance.rst
2015-04-01 10:50:30 +02:00

183 lines
5 KiB
Scala
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Copyright (C) 2009-2015 Typesafe Inc. <http://www.typesafe.com>
*/
package docs.actor
import language.postfixOps
import akka.actor.{ ActorSystem, ActorRef, Props, Terminated }
import FaultHandlingDocSpec._
//#testkit
import com.typesafe.config.{ Config, ConfigFactory }
import org.scalatest.{ FlatSpecLike, Matchers, BeforeAndAfterAll }
import akka.testkit.{ TestActors, TestKit, ImplicitSender, EventFilter }
//#testkit
object FaultHandlingDocSpec {
//#supervisor
//#child
import akka.actor.Actor
//#child
class Supervisor extends Actor {
//#strategy
import akka.actor.OneForOneStrategy
import akka.actor.SupervisorStrategy._
import scala.concurrent.duration._
override val supervisorStrategy =
OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) {
case _: ArithmeticException => Resume
case _: NullPointerException => Restart
case _: IllegalArgumentException => Stop
case _: Exception => Escalate
}
//#strategy
def receive = {
case p: Props => sender() ! context.actorOf(p)
}
}
//#supervisor
//#supervisor2
class Supervisor2 extends Actor {
//#strategy2
import akka.actor.OneForOneStrategy
import akka.actor.SupervisorStrategy._
import scala.concurrent.duration._
override val supervisorStrategy =
OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) {
case _: ArithmeticException => Resume
case _: NullPointerException => Restart
case _: IllegalArgumentException => Stop
case _: Exception => Escalate
}
//#strategy2
def receive = {
case p: Props => sender() ! context.actorOf(p)
}
// override default to kill all children during restart
override def preRestart(cause: Throwable, msg: Option[Any]) {}
}
//#supervisor2
class Supervisor3 extends Actor {
//#default-strategy-fallback
import akka.actor.OneForOneStrategy
import akka.actor.SupervisorStrategy._
import scala.concurrent.duration._
override val supervisorStrategy =
OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) {
case _: ArithmeticException => Resume
case t =>
super.supervisorStrategy.decider.applyOrElse(t, (_: Any) => Escalate)
}
//#default-strategy-fallback
def receive = Actor.emptyBehavior
}
//#child
class Child extends Actor {
var state = 0
def receive = {
case ex: Exception => throw ex
case x: Int => state = x
case "get" => sender() ! state
}
}
//#child
val testConf: Config = ConfigFactory.parseString("""
akka {
loggers = ["akka.testkit.TestEventListener"]
}
""")
}
//#testkit
class FaultHandlingDocSpec(_system: ActorSystem) extends TestKit(_system)
with ImplicitSender with FlatSpecLike with Matchers with BeforeAndAfterAll {
def this() = this(ActorSystem("FaultHandlingDocSpec",
ConfigFactory.parseString("""
akka {
loggers = ["akka.testkit.TestEventListener"]
loglevel = "WARNING"
}
""")))
override def afterAll {
TestKit.shutdownActorSystem(system)
}
"A supervisor" must "apply the chosen strategy for its child" in {
//#testkit
//#create
val supervisor = system.actorOf(Props[Supervisor], "supervisor")
supervisor ! Props[Child]
val child = expectMsgType[ActorRef] // retrieve answer from TestKits testActor
//#create
EventFilter.warning(occurrences = 1) intercept {
//#resume
child ! 42 // set state to 42
child ! "get"
expectMsg(42)
child ! new ArithmeticException // crash it
child ! "get"
expectMsg(42)
//#resume
}
EventFilter[NullPointerException](occurrences = 1) intercept {
//#restart
child ! new NullPointerException // crash it harder
child ! "get"
expectMsg(0)
//#restart
}
EventFilter[IllegalArgumentException](occurrences = 1) intercept {
//#stop
watch(child) // have testActor watch “child”
child ! new IllegalArgumentException // break it
expectMsgPF() { case Terminated(`child`) => () }
//#stop
}
EventFilter[Exception]("CRASH", occurrences = 2) intercept {
//#escalate-kill
supervisor ! Props[Child] // create new child
val child2 = expectMsgType[ActorRef]
watch(child2)
child2 ! "get" // verify it is alive
expectMsg(0)
child2 ! new Exception("CRASH") // escalate failure
expectMsgPF() {
case t @ Terminated(`child2`) if t.existenceConfirmed => ()
}
//#escalate-kill
//#escalate-restart
val supervisor2 = system.actorOf(Props[Supervisor2], "supervisor2")
supervisor2 ! Props[Child]
val child3 = expectMsgType[ActorRef]
child3 ! 23
child3 ! "get"
expectMsg(23)
child3 ! new Exception("CRASH")
child3 ! "get"
expectMsg(0)
//#escalate-restart
}
//#testkit
// code here
}
}
//#testkit