Fixed actor deregistration-by-id issue and added ActorRegistry unit test.

This commit is contained in:
Martin Krasser 2010-02-28 09:13:23 +01:00
parent 8620fb8c06
commit edaad3a165
2 changed files with 69 additions and 3 deletions

View file

@ -10,13 +10,15 @@ import scala.collection.mutable.{ListBuffer, HashMap}
import scala.reflect.Manifest
/**
* Registry holding all actor instances, mapped by class and the actor's id field (which can be set by user-code).
* Registry holding all actor instances, mapped by class, the actor's uuid and the actor's id field (which can be set
* by user-code).
*
* @author <a href="http://jonasboner.com">Jonas Bon&#233;r</a>
*/
object ActorRegistry extends Logging {
private val actorsByClassName = new HashMap[String, List[Actor]]
private val actorsById = new HashMap[String, List[Actor]]
private val actorsByUuid = new HashMap[String, Actor]
/**
* Returns all actors in the system.
@ -50,7 +52,7 @@ object ActorRegistry extends Logging {
}
/**
* Finds all actors that has a specific id.
* Finds all actors that have a specific id.
*/
def actorsFor(id : String): List[Actor] = synchronized {
actorsById.get(id) match {
@ -59,6 +61,13 @@ object ActorRegistry extends Logging {
}
}
/**
* Finds the actor that has a specific uuid.
*/
def actorFor(uuid : String): Option[Actor] = synchronized {
actorsByUuid.get(uuid)
}
def register(actor: Actor) = synchronized {
val className = actor.getClass.getName
actorsByClassName.get(className) match {
@ -71,11 +80,13 @@ object ActorRegistry extends Logging {
case Some(instances) => actorsById + (id -> (actor :: instances))
case None => actorsById + (id -> (actor :: Nil))
}
actorsByUuid + (actor.uuid -> actor)
}
def unregister(actor: Actor) = synchronized {
actorsByClassName - actor.getClass.getName
actorsById - actor.getClass.getName
actorsById - actor.getId
actorsByUuid - actor.uuid
}
def shutdownAll = {

View file

@ -0,0 +1,55 @@
package se.scalablesolutions.akka.actor
import org.junit.Assert._
import org.scalatest.junit.JUnitSuite
import org.junit.Test
class ActorRegistryTest extends JUnitSuite {
val registry = ActorRegistry
@Test
def testRegistrationWithDefaultId {
val actor = new TestActor1
assertEquals(actor.getClass.getName, actor.getId)
testRegistration(actor, classOf[TestActor1])
}
@Test
def testRegistrationWithCustomId {
val actor = new TestActor2
assertEquals("customid", actor.getId)
testRegistration(actor, classOf[TestActor2])
}
private def testRegistration[T <: Actor](actor: T, actorClass: Class[T]) {
assertEquals("non-started actor registered", Nil, registry.actorsFor(actorClass))
assertEquals("non-started actor registered", Nil, registry.actorsFor(actor.getId))
assertEquals("non-started actor registered", None, registry.actorFor(actor.uuid))
actor.start
assertEquals("actor not registered", List(actor), registry.actorsFor(actorClass))
assertEquals("actor not registered", List(actor), registry.actorsFor(actor.getId))
assertEquals("actor not registered", Some(actor), registry.actorFor(actor.uuid))
actor.stop
assertEquals("stopped actor registered", Nil, registry.actorsFor(actorClass))
assertEquals("stopped actor registered", Nil, registry.actorsFor(actor.getId))
assertEquals("stopped actor registered", None, registry.actorFor(actor.uuid))
}
}
class TestActor1 extends Actor {
// use default id
protected def receive = null
}
class TestActor2 extends Actor {
id = "customid"
protected def receive = null
}