Created
April 11, 2011 17:33
-
-
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
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
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