Last active
December 17, 2015 16:08
-
-
Save binarytemple/5636187 to your computer and use it in GitHub Desktop.
Parent unaware of child failures
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import akka.actor.Actor | |
import akka.actor._ | |
import akka.actor.SupervisorStrategy._ | |
import java.lang.UnsupportedOperationException | |
import java.util.concurrent.atomic.AtomicInteger | |
import java.util.concurrent.{TimeUnit, CountDownLatch} | |
import scala.concurrent.duration._ | |
import scala.UnsupportedOperationException | |
class ResumeMakingException extends RuntimeException | |
class RestartMakingException extends RuntimeException | |
class EscalateMakingException extends RuntimeException | |
class StopMakingException extends RuntimeException | |
class FooChild extends Actor { | |
val counter = new AtomicInteger(0) | |
override val supervisorStrategy = | |
OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) { | |
case _: ResumeMakingException ⇒ Resume | |
case _: RestartMakingException ⇒ Restart | |
case _: StopMakingException ⇒ Stop | |
case _: EscalateMakingException ⇒ Escalate | |
} | |
override def postRestart(reason: Throwable) { System.err.println(s"RESTARTED DUE TO: $reason") ; super.postRestart(reason) } | |
def receive = { | |
case 'explode => throw new ResumeMakingException( ) | |
case 'shoot => throw new RestartMakingException( ) | |
case 'implode => throw new EscalateMakingException ( ) | |
case 'armageddon => throw new StopMakingException ( ) | |
case o => println(s"child + $o , counter = ${counter.getAndIncrement}" ) | |
} | |
} | |
class Foo extends Actor { | |
val child = context.actorOf(Props[FooChild]) | |
val dyingChild = context.watch(child) | |
override def unhandled(message: Any) { println(s"Caught unhandled ! ${this}") } | |
def receive = { | |
case 'explode => child ! 'explode | |
case 'shoot => child ! 'shoot | |
case 'implode => child ! 'implode | |
case 'armageddon => child ! 'armageddon | |
case t:Throwable => println(s"Parent caught throwable: ${t}") | |
case s:String => child ! s | |
case o => System.err.println(s"unexpected message $o") | |
} | |
} | |
object Booter { | |
def main(args: Array[String]) { | |
implicit val as = ActorSystem("wombles") | |
val f = as.actorOf(Props[Foo]) | |
f ! "hello before exploding" | |
f ! 'explode | |
f ! "hello after exploding" | |
f ! "hello" | |
f ! "hello before shooting" | |
f ! 'shoot | |
f ! "hello after shooting" | |
f ! "hello" | |
f ! 'implode | |
f ! "hello after imploding" | |
f ! "hello before armageddon" | |
f ! 'armageddon | |
f ! "hello after armageddon" | |
f ! "hello" | |
val c = new CountDownLatch(1) | |
c.await(5, TimeUnit.SECONDS) | |
f ! "hello ! Really, surely after armageddon" | |
val c4 = new CountDownLatch(1) | |
c4.await(5, TimeUnit.SECONDS) | |
as.shutdown() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Here is the program output, the parent never realises that the child threw an exception