Created
January 14, 2013 15:36
-
-
Save rocketraman/4530830 to your computer and use it in GitHub Desktop.
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
import akka.actor._ | |
import akka.japi.Creator | |
import java.util.UUID | |
import ActorFactory.genName | |
import org.slf4j.Logger | |
/** | |
* A base class for all ActorFactory implementations. An ActorFactory can be used to create a new Actor within | |
* the Akka execution context at runtime, but provides the ability to inject dependencies from Spring into the Actor. | |
*/ | |
trait ActorFactory[T <: ActorConfig] { | |
def actorOf(refFactory: ActorRefFactory, props: Props, config: T): ActorRef = { | |
val newActorName = genName(createNewActorName(), autoAddUuid) | |
withActorRef(refFactory.actorOf(withProps(props).withCreator(new Creator[Actor] { | |
def create(): Actor = { | |
newActor(config) | |
} | |
}), newActorName)) | |
} | |
/** | |
* Get the actor name to use. For actors that get created many times in a single actor system, they must | |
* return unique names. | |
*/ | |
def createNewActorName(): String | |
/** | |
* Modifies the actor creation properties. | |
*/ | |
def withProps(props: Props): Props = props | |
/** | |
* Modifies the actor ref. | |
*/ | |
def withActorRef(actorRef: ActorRef): ActorRef = actorRef | |
/** | |
* Creates a new actor instance. As per specs, this must create a new actor Object instance on every call. | |
*/ | |
def newActor(config: T): Actor | |
/** | |
* By default, a UUID is appended to all actor names to make them unique. This behavior can be turned off | |
* by overriding this and returning false. | |
* @return | |
*/ | |
def autoAddUuid: Boolean = true | |
} | |
object ActorFactory { | |
def genName(name: String, autoAddUuid: Boolean): String = { | |
if(autoAddUuid) { | |
name + "-" + UUID.randomUUID() | |
} else { | |
name | |
} | |
} | |
} | |
trait NoConfigActorFactory { | |
def actorOf(refFactory: ActorRefFactory, props: Props): ActorRef = { | |
val newActorName = genName(createNewActorName(), autoAddUuid) | |
withActorRef(refFactory.actorOf(withProps(props).withCreator(new Creator[Actor] { | |
def create(): Actor = { | |
newActor() | |
} | |
}), newActorName)) | |
} | |
/** | |
* Get the actor name to use. For actors that get created many times in a single actor system, they must | |
* return unique names. | |
*/ | |
def createNewActorName(): String | |
/** | |
* Modifies the actor creation properties. | |
*/ | |
def withProps(props: Props): Props = props | |
/** | |
* Modifies the actor ref. | |
*/ | |
def withActorRef(actorRef: ActorRef): ActorRef = actorRef | |
/** | |
* Creates a new actor instance. As per specs, this must create a new actor Object instance on every call. | |
*/ | |
def newActor(): Actor | |
/** | |
* By default, a UUID is appended to all actor names to make them unique. This behavior can be turned off | |
* by overriding this and returning false. | |
* @return | |
*/ | |
def autoAddUuid: Boolean = true | |
} | |
trait NoConfigSingleActorFactory extends NoConfigActorFactory { | |
def log: Logger | |
implicit def refFactory: ActorRefFactory | |
def props: Props | |
lazy val actorPath: ActorPath = actorOf(refFactory, withProps(props)).path | |
/** | |
* Initialize the actor explicitly, if desired. | |
*/ | |
def init() { | |
log.debug("Initialized single actor at path {}.", actorPath) | |
} | |
def actorFor(): ActorRef = { | |
refFactory.actorFor(actorPath) | |
} | |
} | |
/** | |
* Provided for Java access, so they can subclass this and get the actorOf method without having to redefine it | |
*/ | |
abstract class DefaultActorFactory[T <: ActorConfig] extends ActorFactory[T] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment