Created
February 18, 2014 22:54
-
-
Save Kayrnt/9082178 to your computer and use it in GitHub Desktop.
Akka actor system implementation adding a "reboot" on fatal errors
This file contains hidden or 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
| package fr.kayrnt | |
| trait AkkaActorSystem { | |
| implicit val system = AkkaActorSystem.system | |
| } | |
| object AkkaActorSystem { | |
| implicit var system = create() | |
| def create() = TeadsActorSystem() | |
| } |
This file contains hidden or 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
| package fr.kayrnt | |
| import akka.actor.Actor | |
| import akka.actor.Props | |
| object MyApplicationCode extends AkkaActorSystem { | |
| class EchoActor extends Actor { | |
| def receive = { | |
| case x => sender() ! x | |
| } | |
| } | |
| val echo = system.actorOf(Props[EchoActor]) | |
| } |
This file contains hidden or 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
| package akka.actor | |
| import com.typesafe.config.{ ConfigFactory, Config } | |
| import scala.util.control.{ControlThrowable, NonFatal} | |
| import fr.kayrnt.AkkaActorSystem | |
| /** | |
| * This object is designed to "replace" the actual ActorSystem object used to instantiate an Akka actor system. | |
| * The behavior I use in production is to shutdown, gc (at least call it and "pray"), rebuild the actor system | |
| * and finally restart the application... pushing some notifications through emails or chat rooms is also nice. | |
| * | |
| * At this point I wonder what would be the best way to implement a generic way of overriding the Handler. | |
| * I guess I would put the uncaughtExceptionHandler in the constructor and put the current one as a default. | |
| * | |
| * | |
| * | |
| */ | |
| object RebootActorSystem { | |
| def apply(name: String = "default"): ActorSystem = { | |
| val classLoader = ActorSystem.findClassLoader() | |
| apply(name, ConfigFactory.load(classLoader), classLoader) | |
| } | |
| def apply(name: String, config: Config, classLoader: ClassLoader): ActorSystem = new RebootActorSystemImpl(name, config, classLoader).start() | |
| class RebootActorSystemImpl(name: String, applicationConfig: Config, classLoader: ClassLoader) extends ActorSystemImpl(name, applicationConfig, classLoader) { | |
| override protected def uncaughtExceptionHandler: Thread.UncaughtExceptionHandler = | |
| new Thread.UncaughtExceptionHandler() { | |
| def uncaughtException(thread: Thread, cause: Throwable): Unit = { | |
| cause match { | |
| case NonFatal(_) | _: InterruptedException | _: NotImplementedError | _: ControlThrowable ⇒ log.error(cause, "Uncaught error from thread [{}]", thread.getName) | |
| case _ ⇒ { | |
| log.error(cause, "Uncaught fatal error from thread [{}] shutting down ActorSystem [{}]", thread.getName, name) | |
| shutdown() | |
| System.gc() | |
| AkkaActorSystem.system = AkkaActorSystem.create() | |
| //MyApplication.entryPoint() | |
| //SomeServiceThrowingANotification.send(alertRoom) | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment