Skip to content

Instantly share code, notes, and snippets.

@binarytemple
Last active December 17, 2015 16:08
Show Gist options
  • Save binarytemple/5636187 to your computer and use it in GitHub Desktop.
Save binarytemple/5636187 to your computer and use it in GitHub Desktop.
Parent unaware of child failures
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()
}
}
@binarytemple
Copy link
Author

Here is the program output, the parent never realises that the child threw an exception

child + hello before exploding   , counter = 0
[ERROR] [05/23/2013 14:45:49.895] [wombles-akka.actor.default-dispatcher-7] [akka://wombles/user/$a/$a] null
ResumeMakingException
    at FooChild$$anonfun$receive$1.applyOrElse(parentchild.scala:31)
    at akka.actor.ActorCell.receiveMessage(ActorCell.scala:425)
    at akka.actor.ActorCell.invoke(ActorCell.scala:386)
    at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:230)
    at akka.dispatch.Mailbox.run(Mailbox.scala:212)
    at akka.dispatch.ForkJoinExecutorConfigurator$MailboxExecutionTask.exec(AbstractDispatcher.scala:506)
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:262)
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:975)
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1478)
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:104)

child + hello after exploding   , counter = 0
child + hello   , counter = 1
child + hello before shooting   , counter = 2
child + hello after shooting   , counter = 0
child + hello   , counter = 1
child + hello after imploding   , counter = 0
child + hello before armageddon   , counter = 1
RESTARTED DUE TO: ResumeMakingException
RESTARTED DUE TO: RestartMakingException
RESTARTED DUE TO: EscalateMakingException
RESTARTED DUE TO: StopMakingException
child + hello after armageddon   , counter = 0
child + hello   , counter = 1
[ERROR] [05/23/2013 14:45:49.916] [wombles-akka.actor.default-dispatcher-8] [akka://wombles/user/$a/$a] null
RestartMakingException
    at FooChild$$anonfun$receive$1.applyOrElse(parentchild.scala:32)
    at akka.actor.ActorCell.receiveMessage(ActorCell.scala:425)
    at akka.actor.ActorCell.invoke(ActorCell.scala:386)
    at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:230)
    at akka.dispatch.Mailbox.run(Mailbox.scala:212)
    at akka.dispatch.ForkJoinExecutorConfigurator$MailboxExecutionTask.exec(AbstractDispatcher.scala:506)
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:262)
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:975)
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1478)
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:104)

[ERROR] [05/23/2013 14:45:49.918] [wombles-akka.actor.default-dispatcher-8] [akka://wombles/user/$a/$a] null
EscalateMakingException
    at FooChild$$anonfun$receive$1.applyOrElse(parentchild.scala:33)
    at akka.actor.ActorCell.receiveMessage(ActorCell.scala:425)
    at akka.actor.ActorCell.invoke(ActorCell.scala:386)
    at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:230)
    at akka.dispatch.Mailbox.run(Mailbox.scala:212)
    at akka.dispatch.ForkJoinExecutorConfigurator$MailboxExecutionTask.exec(AbstractDispatcher.scala:506)
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:262)
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:975)
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1478)
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:104)

[ERROR] [05/23/2013 14:45:49.918] [wombles-akka.actor.default-dispatcher-8] [akka://wombles/user/$a/$a] null
StopMakingException
    at FooChild$$anonfun$receive$1.applyOrElse(parentchild.scala:34)
    at akka.actor.ActorCell.receiveMessage(ActorCell.scala:425)
    at akka.actor.ActorCell.invoke(ActorCell.scala:386)
    at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:230)
    at akka.dispatch.Mailbox.run(Mailbox.scala:212)
    at akka.dispatch.ForkJoinExecutorConfigurator$MailboxExecutionTask.exec(AbstractDispatcher.scala:506)
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:262)
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:975)
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1478)
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:104)

child + hello ! Really, surely after armageddon   , counter = 2

Process finished with exit code 0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment