Reducing object creation per ActorRef + removed unsafe concurrent publication

This commit is contained in:
Viktor Klang 2010-10-20 14:07:18 +02:00
parent aa904136fd
commit b19725915f
2 changed files with 16 additions and 27 deletions

View file

@ -8,13 +8,13 @@ import se.scalablesolutions.akka.dispatch._
import se.scalablesolutions.akka.config.Config._
import se.scalablesolutions.akka.config.Supervision._
import se.scalablesolutions.akka.util.Helpers.{narrow, narrowSilently}
import se.scalablesolutions.akka.util.{Logging, Duration}
import se.scalablesolutions.akka.AkkaException
import java.util.concurrent.TimeUnit
import java.net.InetSocketAddress
import scala.reflect.BeanProperty
import se.scalablesolutions.akka.util. {ReflectiveAccess, Logging, Duration}
/**
* Implements the Transactor abstraction. E.g. a transactional actor.
@ -120,7 +120,15 @@ object Actor extends Logging {
* val actor = actorOf[MyActor].start
* </pre>
*/
def actorOf(clazz: Class[_ <: Actor]): ActorRef = new LocalActorRef(clazz)
def actorOf(clazz: Class[_ <: Actor]): ActorRef = new LocalActorRef(() => {
import ReflectiveAccess.{ createInstance, noParams, noArgs }
createInstance[Actor](clazz.asInstanceOf[Class[_]], noParams, noArgs).getOrElse(
throw new ActorInitializationException(
"Could not instantiate Actor" +
"\nMake sure Actor is NOT defined inside a class/trait," +
"\nif so put it outside the class/trait, f.e. in a companion object," +
"\nOR try to change: 'actorOf[MyActor]' to 'actorOf(new MyActor)'."))
})
/**

View file

@ -635,7 +635,7 @@ trait ActorRef extends ActorRefShared with TransactionManagement with Logging wi
* @author <a href="http://jonasboner.com">Jonas Bon&#233;r</a>
*/
class LocalActorRef private[akka] (
private[this] var actorFactory: Either[Option[Class[_ <: Actor]], Option[() => Actor]] = Left(None))
private[this] val actorFactory: () => Actor)
extends ActorRef with ScalaActorRef {
@volatile
@ -656,9 +656,6 @@ class LocalActorRef private[akka] (
//If it was started inside "newActor", initialize it
if (isRunning) initializeActorInstance
private[akka] def this(clazz: Class[_ <: Actor]) = this(Left(Some(clazz)))
private[akka] def this(factory: () => Actor) = this(Right(Some(factory)))
// used only for deserialization
private[akka] def this(__uuid: Uuid,
__id: String,
@ -885,7 +882,7 @@ class LocalActorRef private[akka] (
* To be invoked from within the actor itself.
*/
def spawn(clazz: Class[_ <: Actor]): ActorRef = guard.withGuard {
spawnButDoNotStart(clazz).start
Actor.actorOf(clazz).start
}
/**
@ -895,7 +892,7 @@ class LocalActorRef private[akka] (
*/
def spawnRemote(clazz: Class[_ <: Actor], hostname: String, port: Int): ActorRef = guard.withGuard {
ensureRemotingEnabled
val actor = spawnButDoNotStart(clazz)
val actor = Actor.actorOf(clazz)
actor.makeRemote(hostname, port)
actor.start
actor
@ -907,7 +904,7 @@ class LocalActorRef private[akka] (
* To be invoked from within the actor itself.
*/
def spawnLink(clazz: Class[_ <: Actor]): ActorRef = guard.withGuard {
val actor = spawnButDoNotStart(clazz)
val actor = Actor.actorOf(clazz)
try {
link(actor)
} finally {
@ -923,7 +920,7 @@ class LocalActorRef private[akka] (
*/
def spawnLinkRemote(clazz: Class[_ <: Actor], hostname: String, port: Int): ActorRef = guard.withGuard {
ensureRemotingEnabled
val actor = spawnButDoNotStart(clazz)
val actor = Actor.actorOf(clazz)
try {
actor.makeRemote(hostname, port)
link(actor)
@ -1147,25 +1144,9 @@ class LocalActorRef private[akka] (
freshActor.postRestart(reason)
}
private def spawnButDoNotStart(clazz: Class[_ <: Actor]): ActorRef = Actor.actorOf(clazz.newInstance)
private[this] def newActor: Actor = {
Actor.actorRefInCreation.withValue(Some(this)) {
val actor = actorFactory match {
case Left(Some(clazz)) =>
import ReflectiveAccess.{ createInstance, noParams, noArgs }
createInstance(clazz.asInstanceOf[Class[_]], noParams, noArgs).
getOrElse(throw new ActorInitializationException(
"Could not instantiate Actor" +
"\nMake sure Actor is NOT defined inside a class/trait," +
"\nif so put it outside the class/trait, f.e. in a companion object," +
"\nOR try to change: 'actorOf[MyActor]' to 'actorOf(new MyActor)'."))
case Right(Some(factory)) =>
factory()
case _ =>
throw new ActorInitializationException(
"Can't create Actor, no Actor class or factory function in scope")
}
val actor = actorFactory()
if (actor eq null) throw new ActorInitializationException(
"Actor instance passed to ActorRef can not be 'null'")
actor