incorporate review comments

- fix some code formatting & docs
- make ActorCell.parent a volatile var
This commit is contained in:
Roland 2011-12-14 15:24:29 +01:00
parent 7d6c74d75c
commit 49837e4782
8 changed files with 14 additions and 22 deletions

View file

@ -7,5 +7,6 @@ class Supervisor extends Actor {
def receive = { def receive = {
case x: Props sender ! context.actorOf(x) case x: Props sender ! context.actorOf(x)
} }
// need to override the default of stopping all children upon restart, tests rely on keeping them around
override def preRestart(cause: Throwable, msg: Option[Any]) {} override def preRestart(cause: Throwable, msg: Option[Any]) {}
} }

View file

@ -15,6 +15,7 @@ object SupervisorHierarchySpec {
protected def receive = { protected def receive = {
case p: Props sender ! context.actorOf(p) case p: Props sender ! context.actorOf(p)
} }
// test relies on keeping children around during restart
override def preRestart(cause: Throwable, msg: Option[Any]) {} override def preRestart(cause: Throwable, msg: Option[Any]) {}
override def postRestart(reason: Throwable) = { override def postRestart(reason: Throwable) = {
countDown.countDown() countDown.countDown()

View file

@ -37,7 +37,7 @@ akka {
actor { actor {
provider = "akka.actor.LocalActorRefProvider" provider = "akka.actor.LocalActorRefProvider"
creation-timeout = 20s # Timeout for ActorSystem.actorOf creation-timeout = 20s # Timeout for ActorSystem.actorOf
reaper-period = 5s # frequency with which stopping actors are prodded in case they had to be removed from their parents reaper-interval = 5s # frequency with which stopping actors are prodded in case they had to be removed from their parents
timeout = 5s # Default timeout for Future based invocations timeout = 5s # Default timeout for Future based invocations
# - Actor: ask && ? # - Actor: ask && ?
# - UntypedActor: ask # - UntypedActor: ask

View file

@ -185,7 +185,7 @@ private[akka] class ActorCell(
val system: ActorSystemImpl, val system: ActorSystemImpl,
val self: InternalActorRef, val self: InternalActorRef,
val props: Props, val props: Props,
final val parent: InternalActorRef, @volatile var parent: InternalActorRef,
/*no member*/ _receiveTimeout: Option[Duration], /*no member*/ _receiveTimeout: Option[Duration],
var hotswap: Stack[PartialFunction[Any, Unit]]) extends UntypedActorContext { var hotswap: Stack[PartialFunction[Any, Unit]]) extends UntypedActorContext {

View file

@ -240,6 +240,10 @@ trait ActorRefFactory {
* an asynchronous operation, i.e. involves a message send, but if invoked * an asynchronous operation, i.e. involves a message send, but if invoked
* on an [[akka.actor.ActorContext]] if operating on a child of that * on an [[akka.actor.ActorContext]] if operating on a child of that
* context it will free up the name for immediate reuse. * context it will free up the name for immediate reuse.
*
* When invoked on [[akka.actor.ActorSystem]] for a top-level actor, this
* method sends a message to the guardian actor and blocks waiting for a reply,
* see `akka.actor.creation-timeout` in the `reference.conf`.
*/ */
def stop(actor: ActorRef): Unit def stop(actor: ActorRef): Unit
} }

View file

@ -73,7 +73,7 @@ object ActorSystem {
val ProviderClass = getString("akka.actor.provider") val ProviderClass = getString("akka.actor.provider")
val CreationTimeout = Timeout(Duration(getMilliseconds("akka.actor.creation-timeout"), MILLISECONDS)) val CreationTimeout = Timeout(Duration(getMilliseconds("akka.actor.creation-timeout"), MILLISECONDS))
val ReaperPeriod = Duration(getMilliseconds("akka.actor.reaper-period"), MILLISECONDS) val ReaperInterval = Duration(getMilliseconds("akka.actor.reaper-interval"), MILLISECONDS)
val ActorTimeout = Timeout(Duration(getMilliseconds("akka.actor.timeout"), MILLISECONDS)) val ActorTimeout = Timeout(Duration(getMilliseconds("akka.actor.timeout"), MILLISECONDS))
val SerializeAllMessages = getBoolean("akka.actor.serialize-messages") val SerializeAllMessages = getBoolean("akka.actor.serialize-messages")
@ -441,7 +441,7 @@ class ActorSystemImpl(val name: String, applicationConfig: Config) extends Actor
this this
} }
lazy val locker: Locker = new Locker(scheduler, ReaperPeriod, lookupRoot.path / "locker", deathWatch) lazy val locker: Locker = new Locker(scheduler, ReaperInterval, lookupRoot.path / "locker", deathWatch)
def start() = _start def start() = _start

View file

@ -15,7 +15,7 @@ class Locker(scheduler: Scheduler, period: Duration, val path: ActorPath, val de
def run = { def run = {
val iter = heap.entrySet.iterator val iter = heap.entrySet.iterator
while (iter.hasNext) { while (iter.hasNext) {
val soul = iter.next(); val soul = iter.next()
deathWatch.subscribe(Locker.this, soul.getKey) // in case Terminated got lost somewhere deathWatch.subscribe(Locker.this, soul.getKey) // in case Terminated got lost somewhere
soul.getKey match { soul.getKey match {
case _: LocalActorRef // nothing to do, they know what they signed up for case _: LocalActorRef // nothing to do, they know what they signed up for
@ -41,24 +41,10 @@ class Locker(scheduler: Scheduler, period: Duration, val path: ActorPath, val de
soul match { soul match {
case local: LocalActorRef case local: LocalActorRef
val cell = local.underlying val cell = local.underlying
rebind(cell, cell.getClass) cell.parent = this
case _ case _
} }
case _ // ignore case _ // ignore
} }
@scala.annotation.tailrec
final private def rebind(cell: ActorCell, clazz: Class[_]): Unit = {
try {
val heart = clazz.getDeclaredField("parent")
heart.setAccessible(true)
heart.set(cell, this)
return
} catch {
case _: NoSuchFieldException
}
val sc = clazz.getSuperclass
if (sc != null) rebind(cell, sc)
}
} }