Skip to content

Instantly share code, notes, and snippets.

@derekwyatt
Created April 11, 2011 17:33
Show Gist options
  • Save derekwyatt/913901 to your computer and use it in GitHub Desktop.
Save derekwyatt/913901 to your computer and use it in GitHub Desktop.
I threw this together to illustrate the idea of sliding in an alternate factory to use during Actor restarts, as opposed to the initial one that was used on construction
diff --git a/akka-actor/src/main/scala/akka/actor/ActorRef.scala b/akka-actor/src/main/scala/akka/actor/ActorRef.scala
index ce62987..fbe6eef 100644
--- a/akka-actor/src/main/scala/akka/actor/ActorRef.scala
+++ b/akka-actor/src/main/scala/akka/actor/ActorRef.scala
@@ -949,7 +949,8 @@ class LocalActorRef private[akka] (
failedActor.postRestart(reason)
case _ =>
failedActor.preRestart(reason)
- val freshActor = newActor
+ val restartFactory = newActor(failedActor.getRestartFactory(reason).getOrElse(actorFactory))
+ val freshActor = restartFactory
setActorSelfFields(failedActor, null) // Only null out the references if we could instantiate the new actor
actorInstance.set(freshActor) // Assign it here so if preStart fails, we can null out the sef-refs next call
freshActor.preStart
@@ -1031,10 +1032,10 @@ class LocalActorRef private[akka] (
// ========= PRIVATE FUNCTIONS =========
- private[this] def newActor: Actor = {
+ private[this] def newActor(aFactory: () => Actor): Actor = {
try {
Actor.actorRefInCreation.value = Some(this)
- val a = actorFactory()
+ val a = aFactory()
if (a eq null) throw new ActorInitializationException("Actor instance passed to ActorRef can not be 'null'")
a
} finally {
@@ -1042,6 +1043,10 @@ class LocalActorRef private[akka] (
}
}
+ private[this] def newActor: Actor = {
+ newActor(actorFactory)
+ }
+
private def shutDownTemporaryActor(temporaryActor: ActorRef) {
temporaryActor.stop
_linkedActors.remove(temporaryActor.uuid) // remove the temporary actor
diff --git a/akka-actor/src/main/scala/akka/actor/Actor.scala b/akka-actor/src/main/scala/akka/actor/Actor.scala
index db06a04..e642f7e 100644
--- a/akka-actor/src/main/scala/akka/actor/Actor.scala
+++ b/akka-actor/src/main/scala/akka/actor/Actor.scala
@@ -385,6 +385,13 @@ trait Actor {
def preRestart(reason: Throwable) {}
/**
+ * User overridable factory accessor
+ * <p/>
+ * Is called on a crashed Actor right AFTER preRestart to allow for specification of a factory to be used to construct a new instance.
+ */
+ def getRestartFactory(reason: Throwable): Option[() => Actor] = { None }
+
+ /**
* User overridable callback.
* <p/>
* Is called right AFTER restart on the newly created Actor to allow reinitialization after an Actor crash.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment