add and verify Java API for actorFor/ActorPath, fixes #1343
This commit is contained in:
parent
56dc18106b
commit
a0a44abe0d
6 changed files with 80 additions and 31 deletions
|
|
@ -51,7 +51,11 @@ class ActorLookupSpec extends AkkaSpec with DefaultTimeout {
|
|||
system.actorFor(system / "c1") must be === c1
|
||||
system.actorFor(system / "c2") must be === c2
|
||||
system.actorFor(system / "c2" / "c21") must be === c21
|
||||
system.actorFor(system child "c2" child "c21") must be === c21 // test Java API
|
||||
system.actorFor(system / Seq("c2", "c21")) must be === c21
|
||||
|
||||
import scala.collection.JavaConverters._
|
||||
system.actorFor(system descendant Seq("c2", "c21").asJava) // test Java API
|
||||
}
|
||||
|
||||
"find actors by looking up their string representation" in {
|
||||
|
|
@ -75,7 +79,7 @@ class ActorLookupSpec extends AkkaSpec with DefaultTimeout {
|
|||
"find actors by looking up their path elements" in {
|
||||
system.actorFor(c1.path.elements) must be === c1
|
||||
system.actorFor(c2.path.elements) must be === c2
|
||||
system.actorFor(c21.path.elements) must be === c21
|
||||
system.actorFor(c21.path.getElements) must be === c21 // test Java API
|
||||
}
|
||||
|
||||
"find system-generated actors" in {
|
||||
|
|
@ -190,6 +194,8 @@ class ActorLookupSpec extends AkkaSpec with DefaultTimeout {
|
|||
}
|
||||
|
||||
"return deadLetters for non-existing paths" in {
|
||||
import scala.collection.JavaConverters._
|
||||
|
||||
def checkOne(looker: ActorRef, query: Query) {
|
||||
(looker ? query).get must be === system.deadLetters
|
||||
}
|
||||
|
|
@ -198,6 +204,8 @@ class ActorLookupSpec extends AkkaSpec with DefaultTimeout {
|
|||
LookupString(""),
|
||||
LookupString("akka://all-systems/Nobody"),
|
||||
LookupPath(system / "hallo"),
|
||||
LookupPath(looker.path child "hallo"), // test Java API
|
||||
LookupPath(looker.path descendant Seq("a", "b").asJava), // test Java API
|
||||
LookupElems(Seq()),
|
||||
LookupElems(Seq("a"))) foreach (checkOne(looker, _))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,16 +49,37 @@ sealed trait ActorPath extends Comparable[ActorPath] {
|
|||
*/
|
||||
def /(child: String): ActorPath
|
||||
|
||||
/**
|
||||
* ''Java API'': Create a new child actor path.
|
||||
*/
|
||||
def child(child: String): ActorPath = /(child)
|
||||
|
||||
/**
|
||||
* Recursively create a descendant’s path by appending all child names.
|
||||
*/
|
||||
def /(child: Iterable[String]): ActorPath = (this /: child)(_ / _)
|
||||
|
||||
/**
|
||||
* Sequence of names for this path. Performance implication: has to allocate a list.
|
||||
* ''Java API'': Recursively create a descendant’s path by appending all child names.
|
||||
*/
|
||||
def descendant(names: java.lang.Iterable[String]): ActorPath = {
|
||||
import scala.collection.JavaConverters._
|
||||
/(names.asScala)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sequence of names for this path from root to this. Performance implication: has to allocate a list.
|
||||
*/
|
||||
def elements: Iterable[String]
|
||||
|
||||
/**
|
||||
* ''Java API'': Sequence of names for this path from root to this. Performance implication: has to allocate a list.
|
||||
*/
|
||||
def getElements: java.lang.Iterable[String] = {
|
||||
import scala.collection.JavaConverters._
|
||||
elements.asJava
|
||||
}
|
||||
|
||||
/**
|
||||
* Walk up the tree to obtain and return the RootActorPath.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ private[akka] abstract class InternalActorRef extends ActorRef with ScalaActorRe
|
|||
* trailing "" element must be disregarded. If the requested path does not
|
||||
* exist, return Nobody.
|
||||
*/
|
||||
def getChild(name: Iterable[String]): InternalActorRef
|
||||
def getChild(name: Iterator[String]): InternalActorRef
|
||||
}
|
||||
|
||||
private[akka] case object Nobody extends MinimalActorRef {
|
||||
|
|
@ -256,26 +256,27 @@ class LocalActorRef private[akka] (
|
|||
}
|
||||
}
|
||||
|
||||
def getChild(names: Iterable[String]): InternalActorRef = {
|
||||
def getChild(names: Iterator[String]): InternalActorRef = {
|
||||
/*
|
||||
* The idea is to recursively descend as far as possible with LocalActor
|
||||
* Refs and hand over to that “foreign” child when we encounter it.
|
||||
*/
|
||||
@tailrec
|
||||
def rec(ref: InternalActorRef, name: Iterable[String]): InternalActorRef = ref match {
|
||||
def rec(ref: InternalActorRef, name: Iterator[String]): InternalActorRef =
|
||||
ref match {
|
||||
case l: LocalActorRef ⇒
|
||||
val n = name.head
|
||||
val rest = name.tail
|
||||
val n = name.next()
|
||||
val next = n match {
|
||||
case ".." ⇒ l.getParent
|
||||
case "" ⇒ l
|
||||
case _ ⇒ l.getSingleChild(n)
|
||||
}
|
||||
if (next == Nobody || rest.isEmpty) next else rec(next, rest)
|
||||
if (next == Nobody || name.isEmpty) next else rec(next, name)
|
||||
case _ ⇒
|
||||
ref.getChild(name)
|
||||
}
|
||||
rec(this, names)
|
||||
if (names.isEmpty) this
|
||||
else rec(this, names)
|
||||
}
|
||||
|
||||
// ========= AKKA PROTECTED FUNCTIONS =========
|
||||
|
|
@ -326,9 +327,11 @@ case class SerializedActorRef(path: String) {
|
|||
trait MinimalActorRef extends InternalActorRef {
|
||||
|
||||
def getParent: InternalActorRef = Nobody
|
||||
def getChild(name: Iterable[String]): InternalActorRef =
|
||||
if (name.size == 1 && name.head.isEmpty) this
|
||||
def getChild(names: Iterator[String]): InternalActorRef = {
|
||||
val dropped = names.dropWhile(_.isEmpty)
|
||||
if (dropped.isEmpty) this
|
||||
else Nobody
|
||||
}
|
||||
|
||||
//FIXME REMOVE THIS, ticket #1416
|
||||
//FIXME REMOVE THIS, ticket #1415
|
||||
|
|
|
|||
|
|
@ -287,7 +287,7 @@ trait ActorRefFactory {
|
|||
def actorFor(path: Iterable[String]): ActorRef = provider.actorFor(lookupRoot, path)
|
||||
|
||||
/**
|
||||
* Look-up an actor by applying the given path elements, starting from the
|
||||
* ''Java API'': Look-up an actor by applying the given path elements, starting from the
|
||||
* current context, where `".."` signifies the parent of an actor.
|
||||
*
|
||||
* Example:
|
||||
|
|
@ -307,7 +307,7 @@ trait ActorRefFactory {
|
|||
*
|
||||
* For maximum performance use a collection with efficient head & tail operations.
|
||||
*/
|
||||
def actorFor(path: java.util.List[String]): ActorRef = {
|
||||
def actorFor(path: java.lang.Iterable[String]): ActorRef = {
|
||||
import scala.collection.JavaConverters._
|
||||
provider.actorFor(lookupRoot, path.asScala)
|
||||
}
|
||||
|
|
@ -462,13 +462,17 @@ class LocalActorRefProvider(
|
|||
val children = new ConcurrentHashMap[String, AskActorRef]
|
||||
def path = tempNode
|
||||
override def getParent = rootGuardian
|
||||
override def getChild(name: Iterable[String]): InternalActorRef = {
|
||||
children.get(name.head) match {
|
||||
override def getChild(name: Iterator[String]): InternalActorRef = {
|
||||
if (name.isEmpty) this
|
||||
else {
|
||||
val n = name.next()
|
||||
if (n.isEmpty) this
|
||||
else children.get(n) match {
|
||||
case null ⇒ Nobody
|
||||
case some ⇒
|
||||
val t = name.tail
|
||||
if (t.isEmpty) some
|
||||
else some.getChild(t)
|
||||
if (name.isEmpty) some
|
||||
else some.getChild(name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -497,7 +501,7 @@ class LocalActorRefProvider(
|
|||
|
||||
def actorFor(ref: InternalActorRef, path: Iterable[String]): InternalActorRef =
|
||||
if (path.isEmpty) deadLetters
|
||||
else ref.getChild(path) match {
|
||||
else ref.getChild(path.iterator) match {
|
||||
case Nobody ⇒ deadLetters
|
||||
case x ⇒ x
|
||||
}
|
||||
|
|
|
|||
|
|
@ -218,11 +218,24 @@ abstract class ActorSystem extends ActorRefFactory {
|
|||
*/
|
||||
def /(name: String): ActorPath
|
||||
|
||||
/**
|
||||
* ''Java API'': Create a new child actor path.
|
||||
*/
|
||||
def child(child: String): ActorPath = /(child)
|
||||
|
||||
/**
|
||||
* Construct a path below the application guardian to be used with [[ActorSystem.actorFor]].
|
||||
*/
|
||||
def /(name: Iterable[String]): ActorPath
|
||||
|
||||
/**
|
||||
* ''Java API'': Recursively create a descendant’s path by appending all child names.
|
||||
*/
|
||||
def descendant(names: java.lang.Iterable[String]): ActorPath = {
|
||||
import scala.collection.JavaConverters._
|
||||
/(names.asScala)
|
||||
}
|
||||
|
||||
/**
|
||||
* Start-up time in milliseconds since the epoch.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -270,7 +270,7 @@ private[akka] case class RemoteActorRef private[akka] (
|
|||
|
||||
// FIXME RK
|
||||
def getParent = Nobody
|
||||
def getChild(name: Iterable[String]) = Nobody
|
||||
def getChild(name: Iterator[String]) = Nobody
|
||||
|
||||
@volatile
|
||||
private var running: Boolean = true
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue