Skip to content

Instantly share code, notes, and snippets.

@rocketraman
Created January 14, 2013 15:36
Show Gist options
  • Save rocketraman/4530830 to your computer and use it in GitHub Desktop.
Save rocketraman/4530830 to your computer and use it in GitHub Desktop.
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