diff --git a/akka-actor/src/main/scala/akka/actor/ActorRef.scala b/akka-actor/src/main/scala/akka/actor/ActorRef.scala index 719218ce1c..3a7378b97a 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorRef.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorRef.scala @@ -89,9 +89,6 @@ object ActorRef { * Two actor references are compared equal when they have the same path and point to * the same actor incarnation. A reference pointing to a terminated actor doesn't compare * equal to a reference pointing to another (re-created) actor with the same path. - * Actor references acquired with `actorFor` do not always include the full information - * about the underlying actor identity and therefore such references do not always compare - * equal to references acquired with `actorOf`, `sender`, or `context.self`. * * If you need to keep track of actor references in a collection and do not care * about the exact actor incarnation you can use the ``ActorPath`` as key because diff --git a/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala b/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala index 24818061e0..ac0fbe6661 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala @@ -116,29 +116,39 @@ trait ActorRefProvider { async: Boolean): InternalActorRef /** + * INTERNAL API + * * Create actor reference for a specified local or remote path. If no such * actor exists, it will be (equivalent to) a dead letter reference. + * + * Actor references acquired with `actorFor` do not always include the full information + * about the underlying actor identity and therefore such references do not always compare + * equal to references acquired with `actorOf`, `sender`, or `context.self`. */ @deprecated("use actorSelection instead of actorFor", "2.2") - def actorFor(path: ActorPath): InternalActorRef + private[akka] def actorFor(path: ActorPath): InternalActorRef /** + * INTERNAL API + * * Create actor reference for a specified local or remote path, which will * be parsed using java.net.URI. If no such actor exists, it will be * (equivalent to) a dead letter reference. If `s` is a relative URI, resolve * it relative to the given ref. */ @deprecated("use actorSelection instead of actorFor", "2.2") - def actorFor(ref: InternalActorRef, s: String): InternalActorRef + private[akka] def actorFor(ref: InternalActorRef, s: String): InternalActorRef /** + * INTERNAL API + * * Create actor reference for the specified child path starting at the * given starting point. This method always returns an actor which is “logically local”, * i.e. it cannot be used to obtain a reference to an actor which is not * physically or logically attached to this actor system. */ @deprecated("use actorSelection instead of actorFor", "2.2") - def actorFor(ref: InternalActorRef, p: Iterable[String]): InternalActorRef + private[akka] def actorFor(ref: InternalActorRef, p: Iterable[String]): InternalActorRef /** * Create actor reference for a specified path. If no such @@ -235,17 +245,25 @@ trait ActorRefFactory { def actorOf(props: Props, name: String): ActorRef /** + * INTERNAL API + * * Look-up an actor by path; if it does not exist, returns a reference to * the dead-letter mailbox of the [[akka.actor.ActorSystem]]. If the path * point to an actor which is not local, no attempt is made during this * call to verify that the actor it represents does exist or is alive; use * `watch(ref)` to be notified of the target’s termination, which is also * signaled if the queried path cannot be resolved. + * + * Actor references acquired with `actorFor` do not always include the full information + * about the underlying actor identity and therefore such references do not always compare + * equal to references acquired with `actorOf`, `sender`, or `context.self`. */ @deprecated("use actorSelection instead of actorFor", "2.2") - def actorFor(path: ActorPath): ActorRef = provider.actorFor(path) + private[akka] def actorFor(path: ActorPath): ActorRef = provider.actorFor(path) /** + * INTERNAL API + * * Look-up an actor by path represented as string. * * Absolute URIs like `akka://appname/user/actorA` are looked up as described @@ -258,11 +276,17 @@ trait ActorRefFactory { * Relative URIs like `myChild/grandChild` or `../myBrother` are looked up * relative to the current context as described for look-ups by * `actorOf(Iterable[String])` + * + * Actor references acquired with `actorFor` do not always include the full information + * about the underlying actor identity and therefore such references do not always compare + * equal to references acquired with `actorOf`, `sender`, or `context.self`. */ @deprecated("use actorSelection instead of actorFor", "2.2") - def actorFor(path: String): ActorRef = provider.actorFor(lookupRoot, path) + private[akka] def actorFor(path: String): ActorRef = provider.actorFor(lookupRoot, path) /** + * INTERNAL API + * * Look-up an actor by applying the given path elements, starting from the * current context, where `".."` signifies the parent of an actor. * @@ -279,11 +303,17 @@ trait ActorRefFactory { * }}} * * For maximum performance use a collection with efficient head & tail operations. + * + * Actor references acquired with `actorFor` do not always include the full information + * about the underlying actor identity and therefore such references do not always compare + * equal to references acquired with `actorOf`, `sender`, or `context.self`. */ @deprecated("use actorSelection instead of actorFor", "2.2") - def actorFor(path: Iterable[String]): ActorRef = provider.actorFor(lookupRoot, path) + private[akka] def actorFor(path: Iterable[String]): ActorRef = provider.actorFor(lookupRoot, path) /** + * INTERNAL API + * * Java API: Look-up an actor by applying the given path elements, starting from the * current context, where `".."` signifies the parent of an actor. * @@ -303,9 +333,13 @@ trait ActorRefFactory { * }}} * * For maximum performance use a collection with efficient head & tail operations. + * + * Actor references acquired with `actorFor` do not always include the full information + * about the underlying actor identity and therefore such references do not always compare + * equal to references acquired with `actorOf`, `sender`, or `context.self`. */ @deprecated("use actorSelection instead of actorFor", "2.2") - def actorFor(path: java.lang.Iterable[String]): ActorRef = provider.actorFor(lookupRoot, immutableSeq(path)) + private[akka] def actorFor(path: java.lang.Iterable[String]): ActorRef = provider.actorFor(lookupRoot, immutableSeq(path)) /** * Construct an [[akka.actor.ActorSelection]] from the given path, which is @@ -633,7 +667,7 @@ private[akka] class LocalActorRefProvider private[akka] ( } @deprecated("use actorSelection instead of actorFor", "2.2") - override def actorFor(ref: InternalActorRef, path: String): InternalActorRef = path match { + private[akka] override def actorFor(ref: InternalActorRef, path: String): InternalActorRef = path match { case RelativeActorPath(elems) ⇒ if (elems.isEmpty) { log.debug("look-up of empty path string [{}] fails (per definition)", path) @@ -647,7 +681,7 @@ private[akka] class LocalActorRefProvider private[akka] ( } @deprecated("use actorSelection instead of actorFor", "2.2") - override def actorFor(path: ActorPath): InternalActorRef = + private[akka] override def actorFor(path: ActorPath): InternalActorRef = if (path.root == rootPath) actorFor(rootGuardian, path.elements) else { log.debug("look-up of foreign ActorPath [{}] failed", path) @@ -655,7 +689,7 @@ private[akka] class LocalActorRefProvider private[akka] ( } @deprecated("use actorSelection instead of actorFor", "2.2") - override def actorFor(ref: InternalActorRef, path: Iterable[String]): InternalActorRef = + private[akka] override def actorFor(ref: InternalActorRef, path: Iterable[String]): InternalActorRef = if (path.isEmpty) { log.debug("look-up of empty path sequence fails (per definition)") deadLetters diff --git a/akka-docs/rst/general/addressing.rst b/akka-docs/rst/general/addressing.rst index 0a1af0bf80..c2a2e0374d 100644 --- a/akka-docs/rst/general/addressing.rst +++ b/akka-docs/rst/general/addressing.rst @@ -95,11 +95,6 @@ may not be inhabited by an actor and the path itself does not have a life-cycle, it never becomes invalid. You can create an actor path without creating an actor, but you cannot create an actor reference without creating corresponding actor. -.. note:: - - That definition does not hold for ``actorFor``, which is one of the reasons why - ``actorFor`` is deprecated in favor of ``actorSelection``. - You can create an actor, terminate it, and then create a new actor with the same actor path. The newly created actor is a new incarnation of the actor. It is not the same actor. An actor reference to the old incarnation is not valid for the new @@ -179,17 +174,6 @@ To acquire an :class:`ActorRef` that is bound to the life-cycle of a specific ac you need to send a message, such as the built-in :class:`Identify` message, to the actor and use the ``sender()`` reference of a reply from the actor. -.. note:: - - ``actorFor`` is deprecated in favor of ``actorSelection`` because actor references - acquired with ``actorFor`` behave differently for local and remote actors. - In the case of a local actor reference, the named actor needs to exist before the - lookup, or else the acquired reference will be an :class:`EmptyLocalActorRef`. - This will be true even if an actor with that exact path is created after acquiring - the actor reference. For remote actor references acquired with `actorFor` the - behaviour is different and sending messages to such a reference will under the hood - look up the actor by path on the remote system for every message send. - Absolute vs. Relative Paths ``````````````````````````` @@ -226,7 +210,7 @@ Selections may be formulated using the :meth:`ActorSystem.actorSelection` and context.actorSelection("../*") ! msg will send `msg` to all siblings including the current actor. As for references -obtained using `actorFor`, a traversal of the supervision hierarchy is done in +obtained using `actorSelection`, a traversal of the supervision hierarchy is done in order to perform the message send. As the exact set of actors which match a selection may change even while a message is making its way to the recipients, it is not possible to watch a selection for liveliness changes. In order to do @@ -237,8 +221,8 @@ release. .. _actorOf-vs-actorSelection: -Summary: ``actorOf`` vs. ``actorSelection`` vs. ``actorFor`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Summary: ``actorOf`` vs. ``actorSelection`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. note:: @@ -253,9 +237,6 @@ Summary: ``actorOf`` vs. ``actorSelection`` vs. ``actorFor`` delivered, i.e. does not create actors, or verify existence of actors when the selection is created. - - ``actorFor`` (deprecated in favor of actorSelection) only ever looks up an - existing actor, i.e. does not create one. - Actor Reference and Path Equality --------------------------------- @@ -267,12 +248,6 @@ actor with the same path. Note that a restart of an actor caused by a failure st means that it is the same actor incarnation, i.e. a restart is not visible for the consumer of the ``ActorRef``. -Remote actor references acquired with ``actorFor`` do not include the full -information about the underlying actor identity and therefore such references -do not compare equal to references acquired with ``actorOf``, ``sender``, -or ``context.self``. Because of this ``actorFor`` is deprecated in favor of -``actorSelection``. - If you need to keep track of actor references in a collection and do not care about the exact actor incarnation you can use the ``ActorPath`` as key, because the identifier of the target actor is not taken into account when comparing actor paths. @@ -285,8 +260,8 @@ DeathWatch will publish its final transition and in general it is not expected to come back to life again (since the actor life cycle does not allow this). While it is possible to create an actor at a later time with an identical path—simply due to it being impossible to enforce the opposite without keeping -the set of all actors ever created available—this is not good practice: remote -actor references acquired with ``actorFor`` which “died” suddenly start to work +the set of all actors ever created available—this is not good practice: +messages sent with ``actorSelection`` to an actor which “died” suddenly start to work again, but without any guarantee of ordering between this transition and any other event, hence the new inhabitant of the path may receive messages which were destined for the previous tenant. diff --git a/akka-docs/rst/java/lambda-actors.rst b/akka-docs/rst/java/lambda-actors.rst index c9ca3501fa..df9a145e37 100644 --- a/akka-docs/rst/java/lambda-actors.rst +++ b/akka-docs/rst/java/lambda-actors.rst @@ -484,17 +484,6 @@ Remote actor addresses may also be looked up, if :ref:`remoting ` An example demonstrating actor look-up is given in :ref:`remote-sample-java`. -.. note:: - - ``actorFor`` is deprecated in favor of ``actorSelection`` because actor references - acquired with ``actorFor`` behaves different for local and remote actors. - In the case of a local actor reference, the named actor needs to exist before the - lookup, or else the acquired reference will be an :class:`EmptyLocalActorRef`. - This will be true even if an actor with that exact path is created after acquiring - the actor reference. For remote actor references acquired with `actorFor` the - behaviour is different and sending messages to such a reference will under the hood - look up the actor by path on the remote system for every message send. - Messages and immutability ========================= diff --git a/akka-docs/rst/java/remoting.rst b/akka-docs/rst/java/remoting.rst index 1346bbc184..3171f7c323 100644 --- a/akka-docs/rst/java/remoting.rst +++ b/akka-docs/rst/java/remoting.rst @@ -188,13 +188,6 @@ Watching Remote Actors Watching a remote actor is not different than watching a local actor, as described in :ref:`deathwatch-java`. -.. warning:: - - *Caveat:* Watching an ``ActorRef`` acquired with ``actorFor`` does not trigger - ``Terminated`` for lost connections. ``actorFor`` is deprecated in favor of - ``actorSelection``. Acquire the ``ActorRef`` to watch with ``Identify`` and - ``ActorIdentity`` as described in :ref:`actorSelection-java`. - Failure Detector ---------------- diff --git a/akka-docs/rst/java/untyped-actors.rst b/akka-docs/rst/java/untyped-actors.rst index 3d26e3c8f3..d8260635c7 100644 --- a/akka-docs/rst/java/untyped-actors.rst +++ b/akka-docs/rst/java/untyped-actors.rst @@ -438,17 +438,6 @@ Remote actor addresses may also be looked up, if :ref:`remoting ` An example demonstrating remote actor look-up is given in :ref:`remote-sample-java`. -.. note:: - - ``actorFor`` is deprecated in favor of ``actorSelection`` because actor references - acquired with ``actorFor`` behave differently for local and remote actors. - In the case of a local actor reference, the named actor needs to exist before the - lookup, or else the acquired reference will be an :class:`EmptyLocalActorRef`. - This will be true even if an actor with that exact path is created after acquiring - the actor reference. For remote actor references acquired with `actorFor` the - behaviour is different and sending messages to such a reference will under the hood - look up the actor by path on the remote system for every message send. - Messages and immutability ========================= diff --git a/akka-docs/rst/scala/actors.rst b/akka-docs/rst/scala/actors.rst index b52cfde7fe..998e82d790 100644 --- a/akka-docs/rst/scala/actors.rst +++ b/akka-docs/rst/scala/actors.rst @@ -475,17 +475,6 @@ Remote actor addresses may also be looked up, if :ref:`remoting An example demonstrating actor look-up is given in :ref:`remote-sample-scala`. -.. note:: - - ``actorFor`` is deprecated in favor of ``actorSelection`` because actor references - acquired with ``actorFor`` behaves different for local and remote actors. - In the case of a local actor reference, the named actor needs to exist before the - lookup, or else the acquired reference will be an :class:`EmptyLocalActorRef`. - This will be true even if an actor with that exact path is created after acquiring - the actor reference. For remote actor references acquired with `actorFor` the - behaviour is different and sending messages to such a reference will under the hood - look up the actor by path on the remote system for every message send. - Messages and immutability ========================= diff --git a/akka-docs/rst/scala/remoting.rst b/akka-docs/rst/scala/remoting.rst index b0136d1ed1..b8cc9a258b 100644 --- a/akka-docs/rst/scala/remoting.rst +++ b/akka-docs/rst/scala/remoting.rst @@ -193,13 +193,6 @@ Watching Remote Actors Watching a remote actor is not different than watching a local actor, as described in :ref:`deathwatch-scala`. -.. warning:: - - *Caveat:* Watching an ``ActorRef`` acquired with ``actorFor`` does not trigger - ``Terminated`` for lost connections. ``actorFor`` is deprecated in favor of - ``actorSelection``. Acquire the ``ActorRef`` to watch with ``Identify`` and - ``ActorIdentity`` as described in :ref:`actorSelection-scala`. - Failure Detector ---------------- diff --git a/akka-remote/src/main/scala/akka/remote/RemoteActorRefProvider.scala b/akka-remote/src/main/scala/akka/remote/RemoteActorRefProvider.scala index 189d0b1310..ac15178be4 100644 --- a/akka-remote/src/main/scala/akka/remote/RemoteActorRefProvider.scala +++ b/akka-remote/src/main/scala/akka/remote/RemoteActorRefProvider.scala @@ -299,7 +299,7 @@ private[akka] class RemoteActorRefProvider( } @deprecated("use actorSelection instead of actorFor", "2.2") - def actorFor(path: ActorPath): InternalActorRef = { + override private[akka] def actorFor(path: ActorPath): InternalActorRef = { if (hasAddress(path.address)) actorFor(rootGuardian, path.elements) else try { new RemoteActorRef(transport, transport.localAddressForRemote(path.address), @@ -312,7 +312,7 @@ private[akka] class RemoteActorRefProvider( } @deprecated("use actorSelection instead of actorFor", "2.2") - def actorFor(ref: InternalActorRef, path: String): InternalActorRef = path match { + override private[akka] def actorFor(ref: InternalActorRef, path: String): InternalActorRef = path match { case ActorPathExtractor(address, elems) ⇒ if (hasAddress(address)) actorFor(rootGuardian, elems) else { @@ -330,7 +330,7 @@ private[akka] class RemoteActorRefProvider( } @deprecated("use actorSelection instead of actorFor", "2.2") - def actorFor(ref: InternalActorRef, path: Iterable[String]): InternalActorRef = + override private[akka] def actorFor(ref: InternalActorRef, path: Iterable[String]): InternalActorRef = local.actorFor(ref, path) def rootGuardianAt(address: Address): ActorRef =