Skip to content

Instantly share code, notes, and snippets.

@Kayrnt
Created February 18, 2014 22:54
Show Gist options
  • Select an option

  • Save Kayrnt/9082178 to your computer and use it in GitHub Desktop.

Select an option

Save Kayrnt/9082178 to your computer and use it in GitHub Desktop.
Akka actor system implementation adding a "reboot" on fatal errors
package fr.kayrnt
trait AkkaActorSystem {
implicit val system = AkkaActorSystem.system
}
object AkkaActorSystem {
implicit var system = create()
def create() = TeadsActorSystem()
}
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])
}
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