diff --git a/akka-actor-migration/src/main/scala/akka/actor/OldActor.scala b/akka-actor-migration/src/main/scala/akka/actor/OldActor.scala index 0a9238209e..e923773bd8 100644 --- a/akka-actor-migration/src/main/scala/akka/actor/OldActor.scala +++ b/akka-actor-migration/src/main/scala/akka/actor/OldActor.scala @@ -10,6 +10,7 @@ import akka.dispatch.OldFuture import akka.util.Duration import java.util.concurrent.TimeUnit import java.net.InetSocketAddress +import akka.migration.AskableActorRef /** * Migration replacement for `object akka.actor.Actor`. @@ -54,7 +55,6 @@ object OldActor { @deprecated("OldActor.remote should not be used", "2.0") lazy val remote: OldRemoteSupport = new OldRemoteSupport - } @deprecated("use Actor", "2.0") @@ -66,6 +66,8 @@ abstract class OldActor extends Actor { implicit def actorRef2OldActorRef(actorRef: ActorRef) = new OldActorRef(actorRef) + implicit def askableActorRef(actorRef: ActorRef): AskableActorRef = new AskableActorRef(actorRef) + @deprecated("Use context.become instead", "2.0") def become(behavior: Receive, discardOld: Boolean = true) = context.become(behavior, discardOld) diff --git a/akka-actor/src/main/scala/akka/pattern/Patterns.scala b/akka-actor/src/main/scala/akka/pattern/Patterns.scala index 600efc367c..b1498ee2d0 100644 --- a/akka-actor/src/main/scala/akka/pattern/Patterns.scala +++ b/akka-actor/src/main/scala/akka/pattern/Patterns.scala @@ -112,13 +112,12 @@ object Patterns { * Recommended usage example: * * {{{ - * val f = ask(worker, request)(timeout) - * flow { - * EnrichedRequest(request, f()) - * } pipeTo nextActor + * final Future f = Patterns.ask(worker, request, timeout); + * // apply some transformation (i.e. enrich with request info) + * final Future transformed = f.map(new akka.japi.Function() { ... }); + * // send it on to the next stage + * Patterns.pipeTo(transformed, nextActor); * }}} - * - * [see [[akka.dispatch.Future]] for a description of `flow`] */ def pipeTo[T](future: Future[T], actorRef: ActorRef): Future[T] = akka.pattern.pipeTo(future, actorRef) diff --git a/akka-docs/project/migration-guide-1.3.x-2.0.x.rst b/akka-docs/project/migration-guide-1.3.x-2.0.x.rst index 33752b8ce7..273d44c1d1 100644 --- a/akka-docs/project/migration-guide-1.3.x-2.0.x.rst +++ b/akka-docs/project/migration-guide-1.3.x-2.0.x.rst @@ -22,8 +22,8 @@ anything is able to run again. Therefore we provide a migration kit that makes it possible to do the migration changes in smaller steps. The migration kit only covers the most common usage of Akka. It is not intended -as a final solution. The whole migration kit is deprecated and will be removed in -Akka 2.1. +as a final solution. The whole migration kit is marked as deprecated and will +be removed in Akka 2.1. The migration kit is provided in separate jar files. Add the following dependency:: @@ -136,7 +136,8 @@ v1.3:: v2.0:: - system.shutdown() + system.shutdown() // from outside of this system + context.system.shutdown() // from inside any actor Documentation: @@ -149,7 +150,11 @@ Identifying Actors In v1.3 actors have ``uuid`` and ``id`` field. In v2.0 each actor has a unique logical ``path``. The ``ActorRegistry`` has been replaced by actor paths and lookup with -``actorFor`` in ``ActorRefProvider`` (``ActorSystem`` or ``ActorContext``). +``actorFor`` in ``ActorRefProvider`` (``ActorSystem`` or ``ActorContext``). It +is no longer possible to obtain references to all actors being implemented by a +certain class (the reason being that this property is not known yet when an +:class:`ActorRef` is created because instantiation of the actor itself is +asynchronous). v1.3:: @@ -170,7 +175,9 @@ Reply to messages ^^^^^^^^^^^^^^^^^ ``self.channel`` has been replaced with unified reply mechanism using ``sender`` (Scala) -or ``getSender()`` (Java). This works for both tell (!) and ask (?). +or ``getSender()`` (Java). This works for both tell (!) and ask (?). Sending to +an actor reference never throws an exception, hence :meth:`tryTell` and +:meth:`tryReply` are removed. v1.3:: @@ -200,6 +207,31 @@ reply to be received; it is independent of the timeout applied when awaiting completion of the :class:`Future`, however, the actor will complete the :class:`Future` with an :class:`AskTimeoutException` when it stops itself. +Also, since the ``ask`` feature is coupling futures and actors, it is no longer +offered on the :class:`ActorRef` itself, but instead as a use pattern to be +imported. While Scala’s implicit conversions enable transparent replacement, +Java code will have to be changed by more than just adding an import statement. + +v1.3:: + + actorRef ? message // Scala + actorRef.ask(message, timeout); // Java + +v2.0 (Scala):: + + import akka.pattern.ask + + actorRef ? message + ask(actorRef, message) // will use `akka.actor.timeout` or implicit Timeout + ask(actorRef, message)(timeout) + +v2.0 (Java):: + + import akka.pattern.Patterns; + + Patterns.ask(actorRef, message) // will use `akka.actor.timeout` + Patterns.ask(actorRef, message, timeout) + Documentation: * :ref:`actors-scala` @@ -325,7 +357,8 @@ v2.0:: import akka.event.Logging - val log = Logging(context.system, this) + val log = Logging(context.system, this) // will include system name in message source + val log = Logging(system.eventStream, this) // will not include system name log.error(exception, message) log.warning(message) log.info(message) @@ -501,17 +534,25 @@ Documentation: Spawn ^^^^^ -``spawn`` has been removed and can be implemented like this, if needed. Be careful to not +``spawn`` has been removed and should be replaced by creating a :class:`Future`. Be careful to not access any shared mutable state closed over by the body. -:: +Scala:: - def spawn(body: ⇒ Unit) { - system.actorOf(Props(ctx ⇒ { case "go" ⇒ try body finally ctx.stop(ctx.self) })) ! "go" - } + Future { doSomething() } // will be executed asynchronously + +Java:: + + Futures.future(new Callable() { + public String call() { + doSomething(); + } + }, executionContext); Documentation: + * :ref:`futures-scala` + * :ref:`futures-java` * :ref:`jmm` HotSwap @@ -521,7 +562,10 @@ In v2.0 ``become`` and ``unbecome`` metods are located in ``ActorContext``, i.e. The special ``HotSwap`` and ``RevertHotswap`` messages in v1.3 has been removed. Similar can be implemented with your own message and using ``context.become`` and ``context.unbecome`` -in the actor receiving the message. +in the actor receiving the message. The rationale is that being able to replace +any actor’s behavior generically is not a good idea because actor implementors +would have no way to defend against that; hence the change to lay it into the +hands of the actor itself. * :ref:`actors-scala` * :ref:`untyped-actors-java`