From a44da38e2b202f57bbaee1cb96697be0b90ddb15 Mon Sep 17 00:00:00 2001 From: Nikolay Botev Date: Sat, 17 Dec 2011 17:18:50 -0800 Subject: [PATCH 01/18] ask-2.0 --- .../src/main/scala/akka/actor/ActorRef.scala | 85 ++----------------- .../scala/akka/actor/ActorRefProvider.scala | 2 + .../src/main/scala/akka/actor/package.scala | 3 + .../src/main/scala/akka/dispatch/Future.scala | 79 +++++++++++++++++ .../docs/actor/FaultHandlingTestBase.java | 19 +++-- .../docs/actor/UntypedActorDocTestBase.java | 3 +- .../akka/docs/future/FutureDocTestBase.java | 3 +- .../code/akka/docs/actor/ActorDocSpec.scala | 5 +- .../code/akka/docs/future/FutureDocSpec.scala | 21 ++--- .../akka/docs/routing/RouterTypeExample.scala | 4 +- .../akka/docs/testkit/TestkitDocSpec.scala | 3 +- .../akka/remote/RemoteActorRefProvider.scala | 13 +-- .../scala/akka/testkit/TestActorRef.scala | 2 +- 13 files changed, 122 insertions(+), 120 deletions(-) diff --git a/akka-actor/src/main/scala/akka/actor/ActorRef.scala b/akka-actor/src/main/scala/akka/actor/ActorRef.scala index f1378db41a..c4009fdbb4 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorRef.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorRef.scala @@ -104,33 +104,6 @@ abstract class ActorRef extends java.lang.Comparable[ActorRef] with Serializable */ final def tell(msg: Any, sender: ActorRef): Unit = this.!(msg)(sender) - /** - * Akka Java API. - * - * Sends a message asynchronously returns a future holding the eventual reply message. - * The Future will be completed with an [[akka.actor.AskTimeoutException]] after the given - * timeout has expired. - * - * NOTE: - * Use this method with care. In most cases it is better to use 'tell' together with the sender - * parameter to implement non-blocking request/response message exchanges. - * - * If you are sending messages using ask and using blocking operations on the Future, such as - * 'get', then you have to use getContext().sender().tell(...) - * in the target actor to send a reply message to the original sender, and thereby completing the Future, - * otherwise the sender will block until the timeout expires. - * - * When using future callbacks, inside actors you need to carefully avoid closing over - * the containing actor’s reference, i.e. do not call methods or access mutable state - * on the enclosing actor from within the callback. This would break the actor - * encapsulation and may introduce synchronization bugs and race conditions because - * the callback will be scheduled concurrently to the enclosing actor. Unfortunately - * there is not yet a way to detect these illegal accesses at compile time. - */ - def ask(message: AnyRef, timeout: Timeout): Future[AnyRef] = ?(message, timeout).asInstanceOf[Future[AnyRef]] - - def ask(message: AnyRef, timeoutMillis: Long): Future[AnyRef] = ask(message, new Timeout(timeoutMillis)) - /** * Forwards the message and passes the original sender actor as the sender. *

@@ -179,35 +152,6 @@ trait ScalaActorRef { ref: ActorRef ⇒ */ def !(message: Any)(implicit sender: ActorRef = null): Unit - /** - * Sends a message asynchronously, returning a future which may eventually hold the reply. - * The Future will be completed with an [[akka.actor.AskTimeoutException]] after the given - * timeout has expired. - * - * NOTE: - * Use this method with care. In most cases it is better to use '!' together with implicit or explicit - * sender parameter to implement non-blocking request/response message exchanges. - * - * If you are sending messages using ask and using blocking operations on the Future, such as - * 'get', then you have to use getContext().sender().tell(...) - * in the target actor to send a reply message to the original sender, and thereby completing the Future, - * otherwise the sender will block until the timeout expires. - * - * When using future callbacks, inside actors you need to carefully avoid closing over - * the containing actor’s reference, i.e. do not call methods or access mutable state - * on the enclosing actor from within the callback. This would break the actor - * encapsulation and may introduce synchronization bugs and race conditions because - * the callback will be scheduled concurrently to the enclosing actor. Unfortunately - * there is not yet a way to detect these illegal accesses at compile time. - */ - def ?(message: Any)(implicit timeout: Timeout): Future[Any] - - /** - * Sends a message asynchronously, returning a future which may eventually hold the reply. - * The implicit parameter with the default value is just there to disambiguate it from the version that takes the - * implicit timeout - */ - def ?(message: Any, timeout: Timeout)(implicit ignore: Int = 0): Future[Any] = ?(message)(timeout) } /** @@ -236,6 +180,7 @@ private[akka] abstract class InternalActorRef extends ActorRef with ScalaActorRe def stop(): Unit def sendSystemMessage(message: SystemMessage): Unit def getParent: InternalActorRef + def provider: ActorRefProvider /** * Obtain ActorRef by possibly traversing the actor tree or looking it up at * some provider-specific location. This method shall return the end result, @@ -321,6 +266,8 @@ private[akka] class LocalActorRef private[akka] ( def getParent: InternalActorRef = actorCell.parent + def provider = actorCell.provider + /** * Method for looking up a single child beneath this actor. Override in order * to inject “synthetic” actor paths like “/temp”. @@ -365,17 +312,6 @@ private[akka] class LocalActorRef private[akka] ( def !(message: Any)(implicit sender: ActorRef = null): Unit = actorCell.tell(message, sender) - def ?(message: Any)(implicit timeout: Timeout): Future[Any] = { - actorCell.provider.ask(timeout) match { - case Some(a) ⇒ - this.!(message)(a) - a.result - case None ⇒ - this.!(message)(null) - Promise[Any]()(actorCell.system.dispatcher) - } - } - def restart(cause: Throwable): Unit = actorCell.restart(cause) @throws(classOf[java.io.ObjectStreamException]) @@ -405,6 +341,8 @@ case class SerializedActorRef(path: String) { trait MinimalActorRef extends InternalActorRef with LocalRef { def getParent: InternalActorRef = Nobody + def provider: ActorRefProvider = + throw new UnsupportedOperationException("Not supported for [%s]".format(getClass.getName)) def getChild(names: Iterator[String]): InternalActorRef = { val dropped = names.dropWhile(_.isEmpty) if (dropped.isEmpty) this @@ -420,9 +358,6 @@ trait MinimalActorRef extends InternalActorRef with LocalRef { def !(message: Any)(implicit sender: ActorRef = null): Unit = () - def ?(message: Any)(implicit timeout: Timeout): Future[Any] = - throw new UnsupportedOperationException("Not supported for [%s]".format(getClass.getName)) - def sendSystemMessage(message: SystemMessage): Unit = () def restart(cause: Throwable): Unit = () @@ -471,13 +406,6 @@ class DeadLetterActorRef(val eventStream: EventStream) extends MinimalActorRef { case _ ⇒ eventStream.publish(DeadLetter(message, sender, this)) } - override def ?(message: Any)(implicit timeout: Timeout): Future[Any] = { - eventStream.publish(DeadLetter(message, this, this)) - // leave this in: guard with good visibility against really stupid/weird errors - assert(brokenPromise != null) - brokenPromise - } - @throws(classOf[java.io.ObjectStreamException]) override protected def writeReplace(): AnyRef = DeadLetterActorRef.serialized } @@ -558,9 +486,6 @@ class AskActorRef( case _ ⇒ } - override def ?(message: Any)(implicit timeout: Timeout): Future[Any] = - Promise.failed(new UnsupportedOperationException("Ask/? is not supported for [%s]".format(getClass.getName)))(dispatcher) - override def isTerminated = result.isCompleted override def stop(): Unit = if (running.getAndSet(false)) { diff --git a/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala b/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala index d940aa2c20..861a234db3 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala @@ -56,6 +56,8 @@ trait ActorRefProvider { def settings: ActorSystem.Settings + def dispatcher: MessageDispatcher + /** * Initialization of an ActorRefProvider happens in two steps: first * construction of the object with settings, eventStream, scheduler, etc. diff --git a/akka-actor/src/main/scala/akka/actor/package.scala b/akka-actor/src/main/scala/akka/actor/package.scala index cfe5bc1b0d..0b06470c79 100644 --- a/akka-actor/src/main/scala/akka/actor/package.scala +++ b/akka-actor/src/main/scala/akka/actor/package.scala @@ -8,6 +8,9 @@ package object actor { implicit def actorRef2Scala(ref: ActorRef): ScalaActorRef = ref.asInstanceOf[ScalaActorRef] implicit def scala2ActorRef(ref: ScalaActorRef): ActorRef = ref.asInstanceOf[ActorRef] + implicit def actorRef2Askable(actorRef: ActorRef) = new dispatch.AskableActorRef(actorRef) + implicit def askable2ActorRef(askable: dispatch.AskableActorRef) = askable.actorRef + type Uuid = com.eaio.uuid.UUID def newUuid(): Uuid = new Uuid() diff --git a/akka-actor/src/main/scala/akka/dispatch/Future.scala b/akka-actor/src/main/scala/akka/dispatch/Future.scala index fea97fbaf3..c70ec32c43 100644 --- a/akka-actor/src/main/scala/akka/dispatch/Future.scala +++ b/akka-actor/src/main/scala/akka/dispatch/Future.scala @@ -24,6 +24,7 @@ import java.util.concurrent.atomic.{ AtomicReferenceFieldUpdater, AtomicInteger, import akka.dispatch.Await.CanAwait import java.util.concurrent._ import akka.actor.ActorSystem +import akka.actor.{ ActorRef, InternalActorRef } object Await { sealed trait CanAwait @@ -53,6 +54,24 @@ object Await { */ object Futures { + def ask(actor: ActorRef, message: Any)(implicit timeout: Timeout): Future[Any] = { + val provider = actor.asInstanceOf[InternalActorRef].provider + provider.ask(timeout) match { + case Some(a) ⇒ + actor.!(message)(a) + a.result + case None ⇒ + actor.!(message)(null) + Promise[Any]()(provider.dispatcher) + } + } + + def ask(actor: ActorRef, message: Any, timeout: Timeout)(implicit ignore: Int = 0): Future[Any] = + ask(actor, message)(timeout) + + def ask(actor: ActorRef, message: Any, timeoutMillis: Long): Future[Any] = + ask(actor, message)(new Timeout(timeoutMillis)) + /** * Java API, equivalent to Future.apply */ @@ -134,6 +153,66 @@ object Futures { } } +final class AskableActorRef(val actorRef: ActorRef) { + + /** + * Akka Java API. + * + * Sends a message asynchronously returns a future holding the eventual reply message. + * The Future will be completed with an [[akka.actor.AskTimeoutException]] after the given + * timeout has expired. + * + * NOTE: + * Use this method with care. In most cases it is better to use 'tell' together with the sender + * parameter to implement non-blocking request/response message exchanges. + * + * If you are sending messages using ask and using blocking operations on the Future, such as + * 'get', then you have to use getContext().sender().tell(...) + * in the target actor to send a reply message to the original sender, and thereby completing the Future, + * otherwise the sender will block until the timeout expires. + * + * When using future callbacks, inside actors you need to carefully avoid closing over + * the containing actor’s reference, i.e. do not call methods or access mutable state + * on the enclosing actor from within the callback. This would break the actor + * encapsulation and may introduce synchronization bugs and race conditions because + * the callback will be scheduled concurrently to the enclosing actor. Unfortunately + * there is not yet a way to detect these illegal accesses at compile time. + */ + def ask(message: AnyRef, timeout: Timeout): Future[AnyRef] = ?(message, timeout).asInstanceOf[Future[AnyRef]] + + def ask(message: AnyRef, timeoutMillis: Long): Future[AnyRef] = ask(message, new Timeout(timeoutMillis)) + + /** + * Sends a message asynchronously, returning a future which may eventually hold the reply. + * The Future will be completed with an [[akka.actor.AskTimeoutException]] after the given + * timeout has expired. + * + * NOTE: + * Use this method with care. In most cases it is better to use '!' together with implicit or explicit + * sender parameter to implement non-blocking request/response message exchanges. + * + * If you are sending messages using ask and using blocking operations on the Future, such as + * 'get', then you have to use getContext().sender().tell(...) + * in the target actor to send a reply message to the original sender, and thereby completing the Future, + * otherwise the sender will block until the timeout expires. + * + * When using future callbacks, inside actors you need to carefully avoid closing over + * the containing actor’s reference, i.e. do not call methods or access mutable state + * on the enclosing actor from within the callback. This would break the actor + * encapsulation and may introduce synchronization bugs and race conditions because + * the callback will be scheduled concurrently to the enclosing actor. Unfortunately + * there is not yet a way to detect these illegal accesses at compile time. + */ + def ?(message: Any)(implicit timeout: Timeout): Future[Any] = Futures.ask(actorRef, message) + + /** + * Sends a message asynchronously, returning a future which may eventually hold the reply. + * The implicit parameter with the default value is just there to disambiguate it from the version that takes the + * implicit timeout + */ + def ?(message: Any, timeout: Timeout)(implicit ignore: Int = 0): Future[Any] = ?(message)(timeout) +} + object Future { /** diff --git a/akka-docs/java/code/akka/docs/actor/FaultHandlingTestBase.java b/akka-docs/java/code/akka/docs/actor/FaultHandlingTestBase.java index 132dc990ee..1bc3b40c4b 100644 --- a/akka-docs/java/code/akka/docs/actor/FaultHandlingTestBase.java +++ b/akka-docs/java/code/akka/docs/actor/FaultHandlingTestBase.java @@ -13,6 +13,7 @@ import akka.actor.Props; import akka.actor.Terminated; import akka.actor.UntypedActor; import akka.dispatch.Await; +import static akka.dispatch.Futures.ask; import akka.util.Duration; import akka.testkit.AkkaSpec; import akka.testkit.TestProbe; @@ -126,19 +127,19 @@ public class FaultHandlingTestBase { //#create Props superprops = new Props(Supervisor.class).withFaultHandler(strategy); ActorRef supervisor = system.actorOf(superprops, "supervisor"); - ActorRef child = (ActorRef) Await.result(supervisor.ask(new Props(Child.class), 5000), timeout); + ActorRef child = (ActorRef) Await.result(ask(supervisor, new Props(Child.class), 5000), timeout); //#create //#resume child.tell(42); - assert Await.result(child.ask("get", 5000), timeout).equals(42); + assert Await.result(ask(child, "get", 5000), timeout).equals(42); child.tell(new ArithmeticException()); - assert Await.result(child.ask("get", 5000), timeout).equals(42); + assert Await.result(ask(child, "get", 5000), timeout).equals(42); //#resume //#restart child.tell(new NullPointerException()); - assert Await.result(child.ask("get", 5000), timeout).equals(0); + assert Await.result(ask(child, "get", 5000), timeout).equals(0); //#restart //#stop @@ -149,9 +150,9 @@ public class FaultHandlingTestBase { //#stop //#escalate-kill - child = (ActorRef) Await.result(supervisor.ask(new Props(Child.class), 5000), timeout); + child = (ActorRef) Await.result(ask(supervisor, new Props(Child.class), 5000), timeout); probe.watch(child); - assert Await.result(child.ask("get", 5000), timeout).equals(0); + assert Await.result(ask(child, "get", 5000), timeout).equals(0); child.tell(new Exception()); probe.expectMsg(new Terminated(child)); //#escalate-kill @@ -159,11 +160,11 @@ public class FaultHandlingTestBase { //#escalate-restart superprops = new Props(Supervisor2.class).withFaultHandler(strategy); supervisor = system.actorOf(superprops, "supervisor2"); - child = (ActorRef) Await.result(supervisor.ask(new Props(Child.class), 5000), timeout); + child = (ActorRef) Await.result(ask(supervisor, new Props(Child.class), 5000), timeout); child.tell(23); - assert Await.result(child.ask("get", 5000), timeout).equals(23); + assert Await.result(ask(child, "get", 5000), timeout).equals(23); child.tell(new Exception()); - assert Await.result(child.ask("get", 5000), timeout).equals(0); + assert Await.result(ask(child, "get", 5000), timeout).equals(0); //#escalate-restart //#testkit } diff --git a/akka-docs/java/code/akka/docs/actor/UntypedActorDocTestBase.java b/akka-docs/java/code/akka/docs/actor/UntypedActorDocTestBase.java index d442ae6461..be164aa850 100644 --- a/akka-docs/java/code/akka/docs/actor/UntypedActorDocTestBase.java +++ b/akka-docs/java/code/akka/docs/actor/UntypedActorDocTestBase.java @@ -11,6 +11,7 @@ import akka.actor.Props; //#import-future import akka.dispatch.Future; +import akka.dispatch.Futures; import akka.dispatch.Await; import akka.util.Duration; import akka.util.Timeout; @@ -117,7 +118,7 @@ public class UntypedActorDocTestBase { }), "myactor"); //#using-ask - Future future = myActor.ask("Hello", 1000); + Future future = Futures.ask(myActor, "Hello", 1000); Object result = Await.result(future, Duration.create(1, TimeUnit.SECONDS)); //#using-ask system.shutdown(); diff --git a/akka-docs/java/code/akka/docs/future/FutureDocTestBase.java b/akka-docs/java/code/akka/docs/future/FutureDocTestBase.java index c3278f23bd..956e72eab9 100644 --- a/akka-docs/java/code/akka/docs/future/FutureDocTestBase.java +++ b/akka-docs/java/code/akka/docs/future/FutureDocTestBase.java @@ -53,7 +53,6 @@ import akka.actor.Status.Failure; import akka.actor.ActorSystem; import akka.actor.UntypedActor; import akka.actor.ActorRef; -import akka.docs.actor.MyUntypedActor; import akka.actor.Props; import akka.dispatch.Futures; @@ -79,7 +78,7 @@ public class FutureDocTestBase { String msg = "hello"; //#ask-blocking Timeout timeout = system.settings().ActorTimeout(); - Future future = actor.ask(msg, timeout); + Future future = Futures.ask(actor, msg, timeout); String result = (String) Await.result(future, timeout.duration()); //#ask-blocking assertEquals("HELLO", result); diff --git a/akka-docs/scala/code/akka/docs/actor/ActorDocSpec.scala b/akka-docs/scala/code/akka/docs/actor/ActorDocSpec.scala index cdba3d07f3..3907e6cf47 100644 --- a/akka-docs/scala/code/akka/docs/actor/ActorDocSpec.scala +++ b/akka-docs/scala/code/akka/docs/actor/ActorDocSpec.scala @@ -8,6 +8,7 @@ import akka.actor.Actor import akka.actor.Props import akka.event.Logging import akka.dispatch.Future +import akka.dispatch.Futures //#imports1 @@ -229,10 +230,10 @@ class ActorDocSpec extends AkkaSpec(Map("akka.loglevel" -> "INFO")) { val myActor = system.actorOf(Props(new MyActor), name = "myactor") implicit val timeout = system.settings.ActorTimeout - val future = myActor ? "hello" + val future = Futures.ask(myActor, "hello") for (x ← future) println(x) //Prints "hello" - val result: Future[Int] = for (x ← (myActor ? 3).mapTo[Int]) yield { 2 * x } + val result: Future[Int] = for (x ← Futures.ask(myActor, 3).mapTo[Int]) yield { 2 * x } //#using-ask system.stop(myActor) diff --git a/akka-docs/scala/code/akka/docs/future/FutureDocSpec.scala b/akka-docs/scala/code/akka/docs/future/FutureDocSpec.scala index 1b6a755ede..bb96a4e3a0 100644 --- a/akka-docs/scala/code/akka/docs/future/FutureDocSpec.scala +++ b/akka-docs/scala/code/akka/docs/future/FutureDocSpec.scala @@ -10,6 +10,7 @@ import akka.actor.Actor import akka.actor.Props import akka.actor.Status.Failure import akka.dispatch.Future +import akka.dispatch.Futures import akka.dispatch.Await import akka.util.duration._ import akka.dispatch.Promise @@ -46,7 +47,7 @@ class FutureDocSpec extends AkkaSpec { import akka.dispatch.Await implicit val timeout = system.settings.ActorTimeout - val future = actor ? msg + val future = Futures.ask(actor, msg) val result = Await.result(future, timeout.duration).asInstanceOf[String] //#ask-blocking result must be("HELLO") @@ -59,7 +60,7 @@ class FutureDocSpec extends AkkaSpec { //#map-to import akka.dispatch.Future - val future: Future[String] = (actor ? msg).mapTo[String] + val future: Future[String] = Futures.ask(actor, msg).mapTo[String] //#map-to Await.result(future, timeout.duration) must be("HELLO") } @@ -149,13 +150,13 @@ class FutureDocSpec extends AkkaSpec { import akka.dispatch.Await //#composing-wrong - val f1 = actor1 ? msg1 - val f2 = actor2 ? msg2 + val f1 = Futures.ask(actor1, msg1) + val f2 = Futures.ask(actor2, msg2) val a = Await.result(f1, 1 second).asInstanceOf[Int] val b = Await.result(f2, 1 second).asInstanceOf[Int] - val f3 = actor3 ? (a + b) + val f3 = Futures.ask(actor3, (a + b)) val result = Await.result(f3, 1 second).asInstanceOf[Int] //#composing-wrong @@ -172,13 +173,13 @@ class FutureDocSpec extends AkkaSpec { import akka.dispatch.Await //#composing - val f1 = actor1 ? msg1 - val f2 = actor2 ? msg2 + val f1 = Futures.ask(actor1, msg1) + val f2 = Futures.ask(actor2, msg2) val f3 = for { a ← f1.mapTo[Int] b ← f2.mapTo[Int] - c ← (actor3 ? (a + b)).mapTo[Int] + c ← Futures.ask(actor3, (a + b)).mapTo[Int] } yield c val result = Await.result(f3, 1 second).asInstanceOf[Int] @@ -191,7 +192,7 @@ class FutureDocSpec extends AkkaSpec { val oddActor = system.actorOf(Props[OddActor]) //#sequence-ask // oddActor returns odd numbers sequentially from 1 as a List[Future[Int]] - val listOfFutures = List.fill(100)((oddActor ? GetNext).mapTo[Int]) + val listOfFutures = List.fill(100)(Futures.ask(oddActor, GetNext).mapTo[Int]) // now we have a Future[List[Int]] val futureList = Future.sequence(listOfFutures) @@ -239,7 +240,7 @@ class FutureDocSpec extends AkkaSpec { val actor = system.actorOf(Props[MyActor]) val msg1 = -1 //#recover - val future = actor ? msg1 recover { + val future = Futures.ask(actor, msg1) recover { case e: ArithmeticException ⇒ 0 } //#recover diff --git a/akka-docs/scala/code/akka/docs/routing/RouterTypeExample.scala b/akka-docs/scala/code/akka/docs/routing/RouterTypeExample.scala index 63338e8357..c366c011c1 100644 --- a/akka-docs/scala/code/akka/docs/routing/RouterTypeExample.scala +++ b/akka-docs/scala/code/akka/docs/routing/RouterTypeExample.scala @@ -7,7 +7,7 @@ import akka.routing.{ ScatterGatherFirstCompletedRouter, BroadcastRouter, Random import annotation.tailrec import akka.actor.{ Props, Actor } import akka.util.duration._ -import akka.dispatch.Await +import akka.dispatch.{ Futures, Await } case class FibonacciNumber(nbr: Int) @@ -71,7 +71,7 @@ class ParentActor extends Actor { Props[FibonacciActor].withRouter(ScatterGatherFirstCompletedRouter(within = 2 seconds)), "router") implicit val timeout = context.system.settings.ActorTimeout - val futureResult = scatterGatherFirstCompletedRouter ? FibonacciNumber(10) + val futureResult = Futures.ask(scatterGatherFirstCompletedRouter, FibonacciNumber(10)) val result = Await.result(futureResult, timeout.duration) //#scatterGatherFirstCompletedRouter println("The result of calculating Fibonacci for 10 is %d".format(result)) diff --git a/akka-docs/scala/code/akka/docs/testkit/TestkitDocSpec.scala b/akka-docs/scala/code/akka/docs/testkit/TestkitDocSpec.scala index 0678860ba9..c646f9ea54 100644 --- a/akka-docs/scala/code/akka/docs/testkit/TestkitDocSpec.scala +++ b/akka-docs/scala/code/akka/docs/testkit/TestkitDocSpec.scala @@ -7,6 +7,7 @@ package akka.docs.testkit import akka.testkit.TestProbe import akka.util.duration._ import akka.actor._ +import akka.dispatch.Futures //#imports-test-probe @@ -204,7 +205,7 @@ class TestkitDocSpec extends AkkaSpec with DefaultTimeout with ImplicitSender { import akka.util.duration._ //#test-probe-reply val probe = TestProbe() - val future = probe.ref ? "hello" + val future = Futures.ask(probe.ref, "hello") probe.expectMsg(0 millis, "hello") // TestActor runs on CallingThreadDispatcher probe.sender ! "world" assert(future.isCompleted && future.value == Some(Right("world"))) diff --git a/akka-remote/src/main/scala/akka/remote/RemoteActorRefProvider.scala b/akka-remote/src/main/scala/akka/remote/RemoteActorRefProvider.scala index 5b748098ac..6f11d4321c 100644 --- a/akka-remote/src/main/scala/akka/remote/RemoteActorRefProvider.scala +++ b/akka-remote/src/main/scala/akka/remote/RemoteActorRefProvider.scala @@ -160,7 +160,7 @@ trait RemoteRef extends ActorRefScope { * This reference is network-aware (remembers its origin) and immutable. */ private[akka] class RemoteActorRef private[akka] ( - provider: RemoteActorRefProvider, + override val provider: RemoteActorRefProvider, remote: RemoteSupport[ParsedTransportAddress], val path: ActorPath, val getParent: InternalActorRef, @@ -185,17 +185,6 @@ private[akka] class RemoteActorRef private[akka] ( override def !(message: Any)(implicit sender: ActorRef = null): Unit = remote.send(message, Option(sender), this, loader) - override def ?(message: Any)(implicit timeout: Timeout): Future[Any] = { - provider.ask(timeout) match { - case Some(a) ⇒ - this.!(message)(a) - a.result - case None ⇒ - this.!(message)(null) - Promise[Any]()(provider.dispatcher) - } - } - def suspend(): Unit = sendSystemMessage(Suspend()) def resume(): Unit = sendSystemMessage(Resume()) diff --git a/akka-testkit/src/main/scala/akka/testkit/TestActorRef.scala b/akka-testkit/src/main/scala/akka/testkit/TestActorRef.scala index eaeecf7487..2d52f21226 100644 --- a/akka-testkit/src/main/scala/akka/testkit/TestActorRef.scala +++ b/akka-testkit/src/main/scala/akka/testkit/TestActorRef.scala @@ -71,7 +71,7 @@ class TestActorRef[T <: Actor]( underlying.actor.asInstanceOf[T] match { case null ⇒ val t = underlying.system.settings.ActorTimeout - Await.result(?(InternalGetActor)(t), t.duration).asInstanceOf[T] + Await.result(this.?(InternalGetActor)(t), t.duration).asInstanceOf[T] case ref ⇒ ref } } From 4270b6f71ba439e2d46d063c1c9f4029459d76c8 Mon Sep 17 00:00:00 2001 From: Nikolay Botev Date: Sat, 17 Dec 2011 22:08:14 -0800 Subject: [PATCH 02/18] ask 2.1 --- .../src/main/scala/akka/actor/ActorRef.scala | 5 ++-- .../scala/akka/actor/ActorRefProvider.scala | 25 ++++++++++++++++--- .../src/main/scala/akka/dispatch/Future.scala | 6 ++--- .../src/main/scala/akka/routing/Routing.scala | 7 ++++-- .../akka/remote/RemoteActorRefProvider.scala | 2 +- .../akka/remote/RemoteCommunicationSpec.scala | 4 +-- 6 files changed, 34 insertions(+), 15 deletions(-) diff --git a/akka-actor/src/main/scala/akka/actor/ActorRef.scala b/akka-actor/src/main/scala/akka/actor/ActorRef.scala index c4009fdbb4..b689aa5370 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorRef.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorRef.scala @@ -466,14 +466,13 @@ class AskTimeoutException(message: String, cause: Throwable) extends TimeoutExce def this(message: String) = this(message, null: Throwable) } -class AskActorRef( +private[akka] final class PromiseActorRef( val path: ActorPath, override val getParent: InternalActorRef, - val dispatcher: MessageDispatcher, + private final val result: Promise[Any], val deathWatch: DeathWatch) extends MinimalActorRef { final val running = new AtomicBoolean(true) - final val result = Promise[Any]()(dispatcher) override def !(message: Any)(implicit sender: ActorRef = null): Unit = if (running.get) message match { case Status.Success(r) ⇒ result.success(r) diff --git a/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala b/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala index 861a234db3..0b3215cd60 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala @@ -104,7 +104,7 @@ trait ActorRefProvider { * Create AskActorRef and register it properly so it can be serialized/deserialized; * caller needs to send the message. */ - def ask(within: Timeout): Option[AskActorRef] + def ask(result: Promise[Any], within: Timeout): Option[ActorRef] /** * This Future is completed upon termination of this ActorRefProvider, which @@ -494,15 +494,14 @@ class LocalActorRefProvider( } } - def ask(within: Timeout): Option[AskActorRef] = { + def ask(result: Promise[Any], within: Timeout): Option[ActorRef] = { (if (within == null) settings.ActorTimeout else within) match { case t if t.duration.length <= 0 ⇒ None case t ⇒ val path = tempPath() val name = path.name - val a = new AskActorRef(path, tempContainer, dispatcher, deathWatch) + val a = new PromiseActorRef(path, tempContainer, result, deathWatch) tempContainer.addChild(name, a) - val result = a.result val f = dispatcher.prerequisites.scheduler.scheduleOnce(t.duration) { result.failure(new AskTimeoutException("Timed out")) } result onComplete { _ ⇒ try { a.stop(); f.cancel() } @@ -510,6 +509,24 @@ class LocalActorRefProvider( } Some(a) + + // Alternative implementation: + // Create a full-blown actor to complete the promise. + // This would also work but not as efficient as PromiseActorRef. + //val b = actorOf(system, Props(new Actor { + // def receive = { + // case Status.Success(r) ⇒ result.success(r) + // case Status.Failure(f) ⇒ result.failure(f) + // case other ⇒ result.success(other) + // } + //}), systemGuardian, systemGuardian.path / "promise" / tempName(), false, None) + //val ff = system.scheduler.scheduleOnce(t.duration) { b.stop() } + //result onComplete { _ ⇒ + // b.stop() + // ff.cancel() + //} + // + //Some(b) } } } diff --git a/akka-actor/src/main/scala/akka/dispatch/Future.scala b/akka-actor/src/main/scala/akka/dispatch/Future.scala index c70ec32c43..fc4225600d 100644 --- a/akka-actor/src/main/scala/akka/dispatch/Future.scala +++ b/akka-actor/src/main/scala/akka/dispatch/Future.scala @@ -56,14 +56,14 @@ object Futures { def ask(actor: ActorRef, message: Any)(implicit timeout: Timeout): Future[Any] = { val provider = actor.asInstanceOf[InternalActorRef].provider - provider.ask(timeout) match { + val promise = Promise[Any]()(provider.dispatcher) + provider.ask(promise, timeout) match { case Some(a) ⇒ actor.!(message)(a) - a.result case None ⇒ actor.!(message)(null) - Promise[Any]()(provider.dispatcher) } + promise } def ask(actor: ActorRef, message: Any, timeout: Timeout)(implicit ignore: Int = 0): Future[Any] = diff --git a/akka-actor/src/main/scala/akka/routing/Routing.scala b/akka-actor/src/main/scala/akka/routing/Routing.scala index 0c02952b3e..36f5fe9670 100644 --- a/akka-actor/src/main/scala/akka/routing/Routing.scala +++ b/akka-actor/src/main/scala/akka/routing/Routing.scala @@ -8,6 +8,7 @@ import java.util.concurrent.atomic.AtomicInteger import scala.collection.JavaConversions._ import akka.util.{ Duration, Timeout } import akka.config.ConfigurationException +import akka.dispatch.Promise /** * A RoutedActorRef is an ActorRef that has a set of connected ActorRef and it uses a Router to @@ -405,8 +406,10 @@ trait ScatterGatherFirstCompletedLike { this: RouterConfig ⇒ { case (sender, message) ⇒ - val asker = context.asInstanceOf[ActorCell].systemImpl.provider.ask(Timeout(within)).get - asker.result.pipeTo(sender) + val provider: ActorRefProvider = context.asInstanceOf[ActorCell].systemImpl.provider + val promise = Promise[Any]()(provider.dispatcher) + val asker = provider.ask(promise, Timeout(within)).get + promise.pipeTo(sender) message match { case _ ⇒ toAll(asker, ref.routees) } diff --git a/akka-remote/src/main/scala/akka/remote/RemoteActorRefProvider.scala b/akka-remote/src/main/scala/akka/remote/RemoteActorRefProvider.scala index 6f11d4321c..5b38996d3b 100644 --- a/akka-remote/src/main/scala/akka/remote/RemoteActorRefProvider.scala +++ b/akka-remote/src/main/scala/akka/remote/RemoteActorRefProvider.scala @@ -138,7 +138,7 @@ class RemoteActorRefProvider( def actorFor(ref: InternalActorRef, path: Iterable[String]): InternalActorRef = local.actorFor(ref, path) - def ask(within: Timeout): Option[AskActorRef] = local.ask(within) + def ask(result: Promise[Any], within: Timeout): Option[ActorRef] = local.ask(result, within) /** * Using (checking out) actor on a specific node. diff --git a/akka-remote/src/test/scala/akka/remote/RemoteCommunicationSpec.scala b/akka-remote/src/test/scala/akka/remote/RemoteCommunicationSpec.scala index dd62ae48e2..0be7c0f361 100644 --- a/akka-remote/src/test/scala/akka/remote/RemoteCommunicationSpec.scala +++ b/akka-remote/src/test/scala/akka/remote/RemoteCommunicationSpec.scala @@ -82,8 +82,8 @@ akka { "support ask" in { Await.result(here ? "ping", timeout.duration) match { - case ("pong", s: AskActorRef) ⇒ // good - case m ⇒ fail(m + " was not (pong, AskActorRef)") + case ("pong", s: PromiseActorRef) ⇒ // good + case m ⇒ fail(m + " was not (pong, AskActorRef)") } } From 0558e11affc0cb8b70637f54d0d2f63b1dcdb135 Mon Sep 17 00:00:00 2001 From: Nikolay Botev Date: Sun, 18 Dec 2011 02:45:21 -0800 Subject: [PATCH 03/18] ask 2.2 --- akka-actor/src/main/scala/akka/actor/ActorSystem.scala | 10 +++++----- akka-actor/src/main/scala/akka/actor/TypedActor.scala | 6 +++--- akka-actor/src/main/scala/akka/event/Logging.scala | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/akka-actor/src/main/scala/akka/actor/ActorSystem.scala b/akka-actor/src/main/scala/akka/actor/ActorSystem.scala index 0e95325ec3..3e9a0a91f4 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorSystem.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorSystem.scala @@ -289,7 +289,7 @@ class ActorSystemImpl(val name: String, applicationConfig: Config) extends Actor private[akka] def systemActorOf(props: Props, name: String): ActorRef = { implicit val timeout = settings.CreationTimeout - Await.result(systemGuardian ? CreateChild(props, name), timeout.duration) match { + Await.result(Futures.ask(systemGuardian, CreateChild(props, name)), timeout.duration) match { case ref: ActorRef ⇒ ref case ex: Exception ⇒ throw ex } @@ -297,7 +297,7 @@ class ActorSystemImpl(val name: String, applicationConfig: Config) extends Actor def actorOf(props: Props, name: String): ActorRef = { implicit val timeout = settings.CreationTimeout - Await.result(guardian ? CreateChild(props, name), timeout.duration) match { + Await.result(Futures.ask(guardian, CreateChild(props, name)), timeout.duration) match { case ref: ActorRef ⇒ ref case ex: Exception ⇒ throw ex } @@ -305,7 +305,7 @@ class ActorSystemImpl(val name: String, applicationConfig: Config) extends Actor def actorOf(props: Props): ActorRef = { implicit val timeout = settings.CreationTimeout - Await.result(guardian ? CreateRandomNameChild(props), timeout.duration) match { + Await.result(Futures.ask(guardian, CreateRandomNameChild(props)), timeout.duration) match { case ref: ActorRef ⇒ ref case ex: Exception ⇒ throw ex } @@ -317,8 +317,8 @@ class ActorSystemImpl(val name: String, applicationConfig: Config) extends Actor val guard = guardian.path val sys = systemGuardian.path path.parent match { - case `guard` ⇒ Await.result(guardian ? StopChild(actor), timeout.duration) - case `sys` ⇒ Await.result(systemGuardian ? StopChild(actor), timeout.duration) + case `guard` ⇒ Await.result(Futures.ask(guardian, StopChild(actor)), timeout.duration) + case `sys` ⇒ Await.result(Futures.ask(systemGuardian, StopChild(actor)), timeout.duration) case _ ⇒ actor.asInstanceOf[InternalActorRef].stop() } } diff --git a/akka-actor/src/main/scala/akka/actor/TypedActor.scala b/akka-actor/src/main/scala/akka/actor/TypedActor.scala index 3dc5d4c000..24ccda0f8d 100644 --- a/akka-actor/src/main/scala/akka/actor/TypedActor.scala +++ b/akka-actor/src/main/scala/akka/actor/TypedActor.scala @@ -398,15 +398,15 @@ object TypedActor extends ExtensionId[TypedActorExtension] with ExtensionIdProvi case _ ⇒ MethodCall(method, args) match { case m if m.isOneWay ⇒ actor ! m; null //Null return value - case m if m.returnsFuture_? ⇒ actor.?(m, timeout) + case m if m.returnsFuture_? ⇒ Futures.ask(actor, m)(timeout) case m if m.returnsJOption_? || m.returnsOption_? ⇒ - val f = actor.?(m, timeout) + val f = Futures.ask(actor, m)(timeout) (try { Await.ready(f, timeout.duration).value } catch { case _: TimeoutException ⇒ None }) match { case None | Some(Right(null)) ⇒ if (m.returnsJOption_?) JOption.none[Any] else None case Some(Right(joption: AnyRef)) ⇒ joption case Some(Left(ex)) ⇒ throw ex } - case m ⇒ Await.result(actor.?(m, timeout), timeout.duration).asInstanceOf[AnyRef] + case m ⇒ Await.result(Futures.ask(actor, m)(timeout), timeout.duration).asInstanceOf[AnyRef] } } } diff --git a/akka-actor/src/main/scala/akka/event/Logging.scala b/akka-actor/src/main/scala/akka/event/Logging.scala index bfd0f2a184..4099dc06b5 100644 --- a/akka-actor/src/main/scala/akka/event/Logging.scala +++ b/akka-actor/src/main/scala/akka/event/Logging.scala @@ -14,7 +14,7 @@ import akka.util.Timeout import java.util.concurrent.atomic.AtomicInteger import scala.util.control.NoStackTrace import java.util.concurrent.TimeoutException -import akka.dispatch.Await +import akka.dispatch.{ Await, Futures } object LoggingBus { implicit def fromActorSystem(system: ActorSystem): LoggingBus = system.eventStream @@ -158,7 +158,7 @@ trait LoggingBus extends ActorEventBus { val name = "log" + Extension(system).id() + "-" + simpleName(clazz) val actor = system.systemActorOf(Props(clazz), name) implicit val timeout = Timeout(3 seconds) - val response = try Await.result(actor ? InitializeLogger(this), timeout.duration) catch { + val response = try Await.result(Futures.ask(actor, InitializeLogger(this)), timeout.duration) catch { case _: TimeoutException ⇒ publish(Warning(simpleName(this), "Logger " + name + " did not respond within " + timeout + " to InitializeLogger(bus)")) } From 877075cdac274fbf2a7efba437dc3ecfddf5c03b Mon Sep 17 00:00:00 2001 From: Nikolay Botev Date: Mon, 19 Dec 2011 15:54:26 -0800 Subject: [PATCH 04/18] ask-2.3 --- .../main/scala/akka/actor/ActorSystem.scala | 14 +++++++----- .../src/main/scala/akka/actor/package.scala | 22 +++++++++++++++++++ .../src/main/scala/akka/dispatch/Future.scala | 12 ++++------ .../docs/transactor/TransactorDocTest.java | 9 ++++---- .../UntypedCoordinatedIncrementTest.java | 5 +++-- .../transactor/UntypedTransactorTest.java | 5 +++-- 6 files changed, 46 insertions(+), 21 deletions(-) diff --git a/akka-actor/src/main/scala/akka/actor/ActorSystem.scala b/akka-actor/src/main/scala/akka/actor/ActorSystem.scala index 3e9a0a91f4..e375f29e4b 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorSystem.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorSystem.scala @@ -287,9 +287,13 @@ class ActorSystemImpl(val name: String, applicationConfig: Config) extends Actor protected def systemImpl = this + @inline private def askAndAwait(actorRef: ActorRef, message: Any)(implicit timeout: akka.util.Timeout): Any = { + Await.result(Futures.ask(actorRef, message), timeout.duration) + } + private[akka] def systemActorOf(props: Props, name: String): ActorRef = { implicit val timeout = settings.CreationTimeout - Await.result(Futures.ask(systemGuardian, CreateChild(props, name)), timeout.duration) match { + askAndAwait(systemGuardian, CreateChild(props, name)) match { case ref: ActorRef ⇒ ref case ex: Exception ⇒ throw ex } @@ -297,7 +301,7 @@ class ActorSystemImpl(val name: String, applicationConfig: Config) extends Actor def actorOf(props: Props, name: String): ActorRef = { implicit val timeout = settings.CreationTimeout - Await.result(Futures.ask(guardian, CreateChild(props, name)), timeout.duration) match { + askAndAwait(guardian, CreateChild(props, name)) match { case ref: ActorRef ⇒ ref case ex: Exception ⇒ throw ex } @@ -305,7 +309,7 @@ class ActorSystemImpl(val name: String, applicationConfig: Config) extends Actor def actorOf(props: Props): ActorRef = { implicit val timeout = settings.CreationTimeout - Await.result(Futures.ask(guardian, CreateRandomNameChild(props)), timeout.duration) match { + askAndAwait(guardian, CreateRandomNameChild(props)) match { case ref: ActorRef ⇒ ref case ex: Exception ⇒ throw ex } @@ -317,8 +321,8 @@ class ActorSystemImpl(val name: String, applicationConfig: Config) extends Actor val guard = guardian.path val sys = systemGuardian.path path.parent match { - case `guard` ⇒ Await.result(Futures.ask(guardian, StopChild(actor)), timeout.duration) - case `sys` ⇒ Await.result(Futures.ask(systemGuardian, StopChild(actor)), timeout.duration) + case `guard` ⇒ askAndAwait(guardian, StopChild(actor)) + case `sys` ⇒ askAndAwait(systemGuardian, StopChild(actor)) case _ ⇒ actor.asInstanceOf[InternalActorRef].stop() } } diff --git a/akka-actor/src/main/scala/akka/actor/package.scala b/akka-actor/src/main/scala/akka/actor/package.scala index 0b06470c79..cedc7befd7 100644 --- a/akka-actor/src/main/scala/akka/actor/package.scala +++ b/akka-actor/src/main/scala/akka/actor/package.scala @@ -41,4 +41,26 @@ package object actor { } } + // Implicit for converting a Promise to an actor. + // Symmetric to the future2actor conversion, which allows + // piping a Future result (read side) to an Actor's mailbox, this + // conversion allows using an Actor to complete a Promise (write side) + // + // Future.ask / actor ? message is now a trivial implementation that can + // also be done in user code (assuming actorRef, timeout and dispatcher implicits): + // + // Future.ask(actor, message) = { + // val promise = Promise[Any]() + // actor ! (message, promise) + // promise + // } + + @inline implicit def promise2actor(promise: akka.dispatch.Promise[Any])(implicit actorRef: ActorRef, timeout: akka.util.Timeout) = { + val provider = actorRef.asInstanceOf[InternalActorRef].provider + provider.ask(promise, timeout) match { + case Some(ref) ⇒ ref + case None ⇒ null + } + } + } diff --git a/akka-actor/src/main/scala/akka/dispatch/Future.scala b/akka-actor/src/main/scala/akka/dispatch/Future.scala index fc4225600d..6eb408fd7a 100644 --- a/akka-actor/src/main/scala/akka/dispatch/Future.scala +++ b/akka-actor/src/main/scala/akka/dispatch/Future.scala @@ -55,14 +55,10 @@ object Await { object Futures { def ask(actor: ActorRef, message: Any)(implicit timeout: Timeout): Future[Any] = { - val provider = actor.asInstanceOf[InternalActorRef].provider - val promise = Promise[Any]()(provider.dispatcher) - provider.ask(promise, timeout) match { - case Some(a) ⇒ - actor.!(message)(a) - case None ⇒ - actor.!(message)(null) - } + implicit val dispatcher = actor.asInstanceOf[InternalActorRef].provider.dispatcher + implicit val actorRefContext = actor // for promise2actor implicit conversion + val promise = Promise[Any]() + actor.!(message)(promise) promise } diff --git a/akka-docs/java/code/akka/docs/transactor/TransactorDocTest.java b/akka-docs/java/code/akka/docs/transactor/TransactorDocTest.java index e6b45f675c..75fa92cd8f 100644 --- a/akka-docs/java/code/akka/docs/transactor/TransactorDocTest.java +++ b/akka-docs/java/code/akka/docs/transactor/TransactorDocTest.java @@ -10,6 +10,7 @@ import org.junit.Test; //#imports import akka.actor.*; import akka.dispatch.Await; +import static akka.dispatch.Futures.ask; import akka.transactor.Coordinated; import akka.util.Duration; import akka.util.Timeout; @@ -30,7 +31,7 @@ public class TransactorDocTest { counter1.tell(new Coordinated(new Increment(counter2), timeout)); - Integer count = (Integer) Await.result(counter1.ask("GetCount", timeout), timeout.duration()); + Integer count = (Integer) Await.result(ask(counter1, "GetCount", timeout), timeout.duration()); //#coordinated-example assertEquals(count, new Integer(1)); @@ -71,7 +72,7 @@ public class TransactorDocTest { counter.tell(coordinated.coordinate(new Increment())); coordinated.await(); - Integer count = (Integer) Await.result(counter.ask("GetCount", timeout), timeout.duration()); + Integer count = (Integer) Await.result(ask(counter, "GetCount", timeout), timeout.duration()); assertEquals(count, new Integer(1)); system.shutdown(); @@ -88,10 +89,10 @@ public class TransactorDocTest { friendlyCounter.tell(coordinated.coordinate(new Increment(friend))); coordinated.await(); - Integer count1 = (Integer) Await.result(friendlyCounter.ask("GetCount", timeout), timeout.duration()); + Integer count1 = (Integer) Await.result(ask(friendlyCounter, "GetCount", timeout), timeout.duration()); assertEquals(count1, new Integer(1)); - Integer count2 = (Integer) Await.result(friend.ask("GetCount", timeout), timeout.duration()); + Integer count2 = (Integer) Await.result(ask(friend, "GetCount", timeout), timeout.duration()); assertEquals(count2, new Integer(1)); system.shutdown(); diff --git a/akka-transactor/src/test/java/akka/transactor/UntypedCoordinatedIncrementTest.java b/akka-transactor/src/test/java/akka/transactor/UntypedCoordinatedIncrementTest.java index 7fce881b2c..267cf261b7 100644 --- a/akka-transactor/src/test/java/akka/transactor/UntypedCoordinatedIncrementTest.java +++ b/akka-transactor/src/test/java/akka/transactor/UntypedCoordinatedIncrementTest.java @@ -18,6 +18,7 @@ import akka.actor.UntypedActor; import akka.actor.UntypedActorFactory; import akka.dispatch.Await; import akka.dispatch.Future; +import static akka.dispatch.Futures.ask; import akka.testkit.AkkaSpec; import akka.testkit.EventFilter; import akka.testkit.ErrorFilter; @@ -80,7 +81,7 @@ public class UntypedCoordinatedIncrementTest { } catch (InterruptedException exception) { } for (ActorRef counter : counters) { - Future future = counter.ask("GetCount", timeout); + Future future = ask(counter, "GetCount", timeout); int count = (Integer) Await.result(future, timeout.duration()); assertEquals(1, count); } @@ -102,7 +103,7 @@ public class UntypedCoordinatedIncrementTest { } catch (InterruptedException exception) { } for (ActorRef counter : counters) { - Futurefuture = counter.ask("GetCount", timeout); + Futurefuture = ask(counter, "GetCount", timeout); int count = (Integer) Await.result(future, timeout.duration()); assertEquals(0, count); } diff --git a/akka-transactor/src/test/java/akka/transactor/UntypedTransactorTest.java b/akka-transactor/src/test/java/akka/transactor/UntypedTransactorTest.java index 9e2cf39f8d..3c80d659cf 100644 --- a/akka-transactor/src/test/java/akka/transactor/UntypedTransactorTest.java +++ b/akka-transactor/src/test/java/akka/transactor/UntypedTransactorTest.java @@ -18,6 +18,7 @@ import akka.actor.UntypedActor; import akka.actor.UntypedActorFactory; import akka.dispatch.Await; import akka.dispatch.Future; +import static akka.dispatch.Futures.ask; import akka.testkit.AkkaSpec; import akka.testkit.EventFilter; import akka.testkit.ErrorFilter; @@ -81,7 +82,7 @@ public class UntypedTransactorTest { } catch (InterruptedException exception) { } for (ActorRef counter : counters) { - Future future = counter.ask("GetCount", timeout); + Future future = ask(counter, "GetCount", timeout); int count = (Integer) Await.result(future, timeout.duration()); assertEquals(1, count); } @@ -103,7 +104,7 @@ public class UntypedTransactorTest { } catch (InterruptedException exception) { } for (ActorRef counter : counters) { - Future future = counter.ask("GetCount", timeout); + Future future = ask(counter, "GetCount", timeout); int count = (Integer) Await.result(future, timeout.duration()); assertEquals(0, count); } From a342bb93eae3bf203bee94e406909c53f5a5df66 Mon Sep 17 00:00:00 2001 From: Nikolay Botev Date: Sat, 31 Dec 2011 17:01:19 -0800 Subject: [PATCH 05/18] WIP: first compiling base --- .../scala/akka/actor/ActorRefProvider.scala | 2 +- .../main/scala/akka/actor/ActorSystem.scala | 15 +-- .../main/scala/akka/actor/TypedActor.scala | 7 +- .../src/main/scala/akka/actor/package.scala | 107 +++++++++++++++++- .../src/main/scala/akka/dispatch/Future.scala | 75 ------------ .../src/main/scala/akka/event/Logging.scala | 5 +- 6 files changed, 115 insertions(+), 96 deletions(-) mode change 100644 => 100755 akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala diff --git a/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala b/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala old mode 100644 new mode 100755 index 0b3215cd60..6af8c36198 --- a/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala @@ -520,7 +520,7 @@ class LocalActorRefProvider( // case other ⇒ result.success(other) // } //}), systemGuardian, systemGuardian.path / "promise" / tempName(), false, None) - //val ff = system.scheduler.scheduleOnce(t.duration) { b.stop() } + //val ff = system.scheduler.scheduleOnce(t.duration) { result.failure(new AskTimeoutException("Timed out")) } //result onComplete { _ ⇒ // b.stop() // ff.cancel() diff --git a/akka-actor/src/main/scala/akka/actor/ActorSystem.scala b/akka-actor/src/main/scala/akka/actor/ActorSystem.scala index e375f29e4b..098099c1d1 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorSystem.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorSystem.scala @@ -7,6 +7,7 @@ import akka.config.ConfigurationException import akka.actor._ import akka.event._ import akka.dispatch._ +import akka.patterns.ask import akka.util.duration._ import akka.util.Timeout import akka.util.Timeout._ @@ -287,13 +288,9 @@ class ActorSystemImpl(val name: String, applicationConfig: Config) extends Actor protected def systemImpl = this - @inline private def askAndAwait(actorRef: ActorRef, message: Any)(implicit timeout: akka.util.Timeout): Any = { - Await.result(Futures.ask(actorRef, message), timeout.duration) - } - private[akka] def systemActorOf(props: Props, name: String): ActorRef = { implicit val timeout = settings.CreationTimeout - askAndAwait(systemGuardian, CreateChild(props, name)) match { + Await.result(systemGuardian ? CreateChild(props, name), timeout.duration) match { case ref: ActorRef ⇒ ref case ex: Exception ⇒ throw ex } @@ -301,7 +298,7 @@ class ActorSystemImpl(val name: String, applicationConfig: Config) extends Actor def actorOf(props: Props, name: String): ActorRef = { implicit val timeout = settings.CreationTimeout - askAndAwait(guardian, CreateChild(props, name)) match { + Await.result(guardian ? CreateChild(props, name), timeout.duration) match { case ref: ActorRef ⇒ ref case ex: Exception ⇒ throw ex } @@ -309,7 +306,7 @@ class ActorSystemImpl(val name: String, applicationConfig: Config) extends Actor def actorOf(props: Props): ActorRef = { implicit val timeout = settings.CreationTimeout - askAndAwait(guardian, CreateRandomNameChild(props)) match { + Await.result(guardian ? CreateRandomNameChild(props), timeout.duration) match { case ref: ActorRef ⇒ ref case ex: Exception ⇒ throw ex } @@ -321,8 +318,8 @@ class ActorSystemImpl(val name: String, applicationConfig: Config) extends Actor val guard = guardian.path val sys = systemGuardian.path path.parent match { - case `guard` ⇒ askAndAwait(guardian, StopChild(actor)) - case `sys` ⇒ askAndAwait(systemGuardian, StopChild(actor)) + case `guard` ⇒ Await.result(guardian ? StopChild(actor), timeout.duration) + case `sys` ⇒ Await.result(systemGuardian ? StopChild(actor), timeout.duration) case _ ⇒ actor.asInstanceOf[InternalActorRef].stop() } } diff --git a/akka-actor/src/main/scala/akka/actor/TypedActor.scala b/akka-actor/src/main/scala/akka/actor/TypedActor.scala index 24ccda0f8d..87fbd98f47 100644 --- a/akka-actor/src/main/scala/akka/actor/TypedActor.scala +++ b/akka-actor/src/main/scala/akka/actor/TypedActor.scala @@ -396,17 +396,18 @@ object TypedActor extends ExtensionId[TypedActorExtension] with ExtensionIdProvi case "equals" ⇒ (args.length == 1 && (proxy eq args(0)) || actor == extension.getActorRefFor(args(0))).asInstanceOf[AnyRef] //Force boxing of the boolean case "hashCode" ⇒ actor.hashCode.asInstanceOf[AnyRef] case _ ⇒ + import akka.patterns.ask MethodCall(method, args) match { case m if m.isOneWay ⇒ actor ! m; null //Null return value - case m if m.returnsFuture_? ⇒ Futures.ask(actor, m)(timeout) + case m if m.returnsFuture_? ⇒ actor.?(m, timeout) case m if m.returnsJOption_? || m.returnsOption_? ⇒ - val f = Futures.ask(actor, m)(timeout) + val f = actor.?(m, timeout) (try { Await.ready(f, timeout.duration).value } catch { case _: TimeoutException ⇒ None }) match { case None | Some(Right(null)) ⇒ if (m.returnsJOption_?) JOption.none[Any] else None case Some(Right(joption: AnyRef)) ⇒ joption case Some(Left(ex)) ⇒ throw ex } - case m ⇒ Await.result(Futures.ask(actor, m)(timeout), timeout.duration).asInstanceOf[AnyRef] + case m ⇒ Await.result(actor.?(m, timeout), timeout.duration).asInstanceOf[AnyRef] } } } diff --git a/akka-actor/src/main/scala/akka/actor/package.scala b/akka-actor/src/main/scala/akka/actor/package.scala index cedc7befd7..f67a3bb1fa 100644 --- a/akka-actor/src/main/scala/akka/actor/package.scala +++ b/akka-actor/src/main/scala/akka/actor/package.scala @@ -8,9 +8,6 @@ package object actor { implicit def actorRef2Scala(ref: ActorRef): ScalaActorRef = ref.asInstanceOf[ScalaActorRef] implicit def scala2ActorRef(ref: ScalaActorRef): ActorRef = ref.asInstanceOf[ActorRef] - implicit def actorRef2Askable(actorRef: ActorRef) = new dispatch.AskableActorRef(actorRef) - implicit def askable2ActorRef(askable: dispatch.AskableActorRef) = askable.actorRef - type Uuid = com.eaio.uuid.UUID def newUuid(): Uuid = new Uuid() @@ -41,7 +38,17 @@ package object actor { } } - // Implicit for converting a Promise to an actor. +} + +package object patterns { + + import akka.actor.{ ActorRef, InternalActorRef } + import akka.dispatch.Promise + import akka.util.Timeout + + implicit def ask(actorRef: ActorRef): AskableActorRef = new AskableActorRef()(actorRef) + + // Implicit for converting a Promise to an ActorRef. // Symmetric to the future2actor conversion, which allows // piping a Future result (read side) to an Actor's mailbox, this // conversion allows using an Actor to complete a Promise (write side) @@ -49,13 +56,13 @@ package object actor { // Future.ask / actor ? message is now a trivial implementation that can // also be done in user code (assuming actorRef, timeout and dispatcher implicits): // - // Future.ask(actor, message) = { + // Patterns.ask(actor, message) = { // val promise = Promise[Any]() // actor ! (message, promise) // promise // } - @inline implicit def promise2actor(promise: akka.dispatch.Promise[Any])(implicit actorRef: ActorRef, timeout: akka.util.Timeout) = { + @inline implicit def promise2actorRef(promise: Promise[Any])(implicit actorRef: ActorRef, timeout: Timeout): ActorRef = { val provider = actorRef.asInstanceOf[InternalActorRef].provider provider.ask(promise, timeout) match { case Some(ref) ⇒ ref @@ -64,3 +71,91 @@ package object actor { } } + +package patterns { + + import akka.actor.{ ActorRef, InternalActorRef } + import akka.dispatch.{ Future, Promise } + import akka.util.Timeout + + final class AskableActorRef(implicit val actorRef: ActorRef) { + + /** + * Akka Java API. + * + * Sends a message asynchronously returns a future holding the eventual reply message. + * The Future will be completed with an [[akka.actor.AskTimeoutException]] after the given + * timeout has expired. + * + * NOTE: + * Use this method with care. In most cases it is better to use 'tell' together with the sender + * parameter to implement non-blocking request/response message exchanges. + * + * If you are sending messages using ask and using blocking operations on the Future, such as + * 'get', then you have to use getContext().sender().tell(...) + * in the target actor to send a reply message to the original sender, and thereby completing the Future, + * otherwise the sender will block until the timeout expires. + * + * When using future callbacks, inside actors you need to carefully avoid closing over + * the containing actor’s reference, i.e. do not call methods or access mutable state + * on the enclosing actor from within the callback. This would break the actor + * encapsulation and may introduce synchronization bugs and race conditions because + * the callback will be scheduled concurrently to the enclosing actor. Unfortunately + * there is not yet a way to detect these illegal accesses at compile time. + */ + def ask(message: AnyRef, timeout: Timeout): Future[AnyRef] = ?(message, timeout).asInstanceOf[Future[AnyRef]] + + def ask(message: AnyRef, timeoutMillis: Long): Future[AnyRef] = ask(message, new Timeout(timeoutMillis)) + + /** + * Sends a message asynchronously, returning a future which may eventually hold the reply. + * The Future will be completed with an [[akka.actor.AskTimeoutException]] after the given + * timeout has expired. + * + * NOTE: + * Use this method with care. In most cases it is better to use '!' together with implicit or explicit + * sender parameter to implement non-blocking request/response message exchanges. + * + * If you are sending messages using ask and using blocking operations on the Future, such as + * 'get', then you have to use getContext().sender().tell(...) + * in the target actor to send a reply message to the original sender, and thereby completing the Future, + * otherwise the sender will block until the timeout expires. + * + * When using future callbacks, inside actors you need to carefully avoid closing over + * the containing actor’s reference, i.e. do not call methods or access mutable state + * on the enclosing actor from within the callback. This would break the actor + * encapsulation and may introduce synchronization bugs and race conditions because + * the callback will be scheduled concurrently to the enclosing actor. Unfortunately + * there is not yet a way to detect these illegal accesses at compile time. + */ + def ?(message: Any)(implicit timeout: Timeout): Future[Any] = { + implicit val dispatcher = actorRef.asInstanceOf[InternalActorRef].provider.dispatcher + val promise = Promise[Any]() + actorRef.!(message)(promise) + promise + } + + /** + * Sends a message asynchronously, returning a future which may eventually hold the reply. + * The implicit parameter with the default value is just there to disambiguate it from the version that takes the + * implicit timeout + */ + def ?(message: Any, timeout: Timeout)(implicit ignore: Int = 0): Future[Any] = ?(message)(timeout) + } + +} + +object Patterns { + + import akka.actor.ActorRef + import akka.dispatch.Future + import akka.patterns.{ ask => actorRef2Askable } + import akka.util.Timeout + + def ask(actor: ActorRef, message: Any, timeout: Timeout): Future[Any] = + actorRef2Askable(actor).?(message)(timeout) + + def ask(actor: ActorRef, message: Any, timeoutMillis: Long): Future[Any] = + actorRef2Askable(actor).?(message)(new Timeout(timeoutMillis)) + +} diff --git a/akka-actor/src/main/scala/akka/dispatch/Future.scala b/akka-actor/src/main/scala/akka/dispatch/Future.scala index 6eb408fd7a..fea97fbaf3 100644 --- a/akka-actor/src/main/scala/akka/dispatch/Future.scala +++ b/akka-actor/src/main/scala/akka/dispatch/Future.scala @@ -24,7 +24,6 @@ import java.util.concurrent.atomic.{ AtomicReferenceFieldUpdater, AtomicInteger, import akka.dispatch.Await.CanAwait import java.util.concurrent._ import akka.actor.ActorSystem -import akka.actor.{ ActorRef, InternalActorRef } object Await { sealed trait CanAwait @@ -54,20 +53,6 @@ object Await { */ object Futures { - def ask(actor: ActorRef, message: Any)(implicit timeout: Timeout): Future[Any] = { - implicit val dispatcher = actor.asInstanceOf[InternalActorRef].provider.dispatcher - implicit val actorRefContext = actor // for promise2actor implicit conversion - val promise = Promise[Any]() - actor.!(message)(promise) - promise - } - - def ask(actor: ActorRef, message: Any, timeout: Timeout)(implicit ignore: Int = 0): Future[Any] = - ask(actor, message)(timeout) - - def ask(actor: ActorRef, message: Any, timeoutMillis: Long): Future[Any] = - ask(actor, message)(new Timeout(timeoutMillis)) - /** * Java API, equivalent to Future.apply */ @@ -149,66 +134,6 @@ object Futures { } } -final class AskableActorRef(val actorRef: ActorRef) { - - /** - * Akka Java API. - * - * Sends a message asynchronously returns a future holding the eventual reply message. - * The Future will be completed with an [[akka.actor.AskTimeoutException]] after the given - * timeout has expired. - * - * NOTE: - * Use this method with care. In most cases it is better to use 'tell' together with the sender - * parameter to implement non-blocking request/response message exchanges. - * - * If you are sending messages using ask and using blocking operations on the Future, such as - * 'get', then you have to use getContext().sender().tell(...) - * in the target actor to send a reply message to the original sender, and thereby completing the Future, - * otherwise the sender will block until the timeout expires. - * - * When using future callbacks, inside actors you need to carefully avoid closing over - * the containing actor’s reference, i.e. do not call methods or access mutable state - * on the enclosing actor from within the callback. This would break the actor - * encapsulation and may introduce synchronization bugs and race conditions because - * the callback will be scheduled concurrently to the enclosing actor. Unfortunately - * there is not yet a way to detect these illegal accesses at compile time. - */ - def ask(message: AnyRef, timeout: Timeout): Future[AnyRef] = ?(message, timeout).asInstanceOf[Future[AnyRef]] - - def ask(message: AnyRef, timeoutMillis: Long): Future[AnyRef] = ask(message, new Timeout(timeoutMillis)) - - /** - * Sends a message asynchronously, returning a future which may eventually hold the reply. - * The Future will be completed with an [[akka.actor.AskTimeoutException]] after the given - * timeout has expired. - * - * NOTE: - * Use this method with care. In most cases it is better to use '!' together with implicit or explicit - * sender parameter to implement non-blocking request/response message exchanges. - * - * If you are sending messages using ask and using blocking operations on the Future, such as - * 'get', then you have to use getContext().sender().tell(...) - * in the target actor to send a reply message to the original sender, and thereby completing the Future, - * otherwise the sender will block until the timeout expires. - * - * When using future callbacks, inside actors you need to carefully avoid closing over - * the containing actor’s reference, i.e. do not call methods or access mutable state - * on the enclosing actor from within the callback. This would break the actor - * encapsulation and may introduce synchronization bugs and race conditions because - * the callback will be scheduled concurrently to the enclosing actor. Unfortunately - * there is not yet a way to detect these illegal accesses at compile time. - */ - def ?(message: Any)(implicit timeout: Timeout): Future[Any] = Futures.ask(actorRef, message) - - /** - * Sends a message asynchronously, returning a future which may eventually hold the reply. - * The implicit parameter with the default value is just there to disambiguate it from the version that takes the - * implicit timeout - */ - def ?(message: Any, timeout: Timeout)(implicit ignore: Int = 0): Future[Any] = ?(message)(timeout) -} - object Future { /** diff --git a/akka-actor/src/main/scala/akka/event/Logging.scala b/akka-actor/src/main/scala/akka/event/Logging.scala index 4099dc06b5..bb0f881c94 100644 --- a/akka-actor/src/main/scala/akka/event/Logging.scala +++ b/akka-actor/src/main/scala/akka/event/Logging.scala @@ -14,7 +14,7 @@ import akka.util.Timeout import java.util.concurrent.atomic.AtomicInteger import scala.util.control.NoStackTrace import java.util.concurrent.TimeoutException -import akka.dispatch.{ Await, Futures } +import akka.dispatch.Await object LoggingBus { implicit def fromActorSystem(system: ActorSystem): LoggingBus = system.eventStream @@ -158,7 +158,8 @@ trait LoggingBus extends ActorEventBus { val name = "log" + Extension(system).id() + "-" + simpleName(clazz) val actor = system.systemActorOf(Props(clazz), name) implicit val timeout = Timeout(3 seconds) - val response = try Await.result(Futures.ask(actor, InitializeLogger(this)), timeout.duration) catch { + import akka.patterns.ask + val response = try Await.result(actor ? InitializeLogger(this), timeout.duration) catch { case _: TimeoutException ⇒ publish(Warning(simpleName(this), "Logger " + name + " did not respond within " + timeout + " to InitializeLogger(bus)")) } From ce1d2f4721a941b49c61f711719a20ccc864ee72 Mon Sep 17 00:00:00 2001 From: Nikolay Botev Date: Sat, 31 Dec 2011 17:42:13 -0800 Subject: [PATCH 06/18] akka.patterns.ask everywhere --- .../ActorFireForgetRequestReplySpec.scala | 1 + .../scala/akka/actor/ActorLifeCycleSpec.scala | 1 + .../scala/akka/actor/ActorLookupSpec.scala | 1 + .../test/scala/akka/actor/ActorRefSpec.scala | 1 + .../scala/akka/actor/ActorTimeoutSpec.scala | 1 + .../scala/akka/actor/DeathWatchSpec.scala | 1 + .../scala/akka/actor/ForwardActorSpec.scala | 1 + .../src/test/scala/akka/actor/IOActor.scala | 1 + .../akka/actor/RestartStrategySpec.scala | 1 + .../test/scala/akka/actor/SchedulerSpec.scala | 1 + .../akka/actor/SupervisorHierarchySpec.scala | 1 + .../scala/akka/actor/SupervisorMiscSpec.scala | 1 + .../scala/akka/actor/SupervisorSpec.scala | 1 + .../scala/akka/actor/SupervisorTreeSpec.scala | 1 + .../test/scala/akka/actor/Ticket669Spec.scala | 1 + .../scala/akka/actor/TypedActorSpec.scala | 1 + .../akka/actor/dispatch/ActorModelSpec.scala | 1 + .../actor/dispatch/DispatcherActorSpec.scala | 1 + .../akka/actor/dispatch/PinnedActorSpec.scala | 1 + .../scala/akka/dataflow/Future2Actor.scala | 1 + .../test/scala/akka/dispatch/FutureSpec.scala | 1 + .../dispatch/PriorityDispatcherSpec.scala | 2 +- .../scala/akka/routing/ActorPoolSpec.scala | 1 + .../routing/ConfiguredLocalRoutingSpec.scala | 1 + .../test/scala/akka/routing/RoutingSpec.scala | 1 + .../akka/serialization/SerializeSpec.scala | 1 + .../scala/akka/ticket/Ticket703Spec.scala | 1 + .../src/main/scala/akka/actor/package.scala | 7 ++++-- .../src/main/scala/akka/agent/Agent.scala | 1 + .../docs/actor/FaultHandlingTestBase.java | 2 +- .../docs/actor/UntypedActorDocTestBase.java | 5 +++-- .../akka/docs/future/FutureDocTestBase.java | 3 ++- .../docs/transactor/TransactorDocTest.java | 2 +- .../code/akka/docs/actor/ActorDocSpec.scala | 8 ++++--- .../code/akka/docs/future/FutureDocSpec.scala | 22 +++++++++---------- .../akka/docs/routing/RouterTypeExample.scala | 5 +++-- .../akka/docs/testkit/TestkitDocSpec.scala | 4 +++- .../docs/transactor/TransactorDocSpec.scala | 1 + .../src/main/scala/akka/remote/Gossiper.scala | 1 + .../DirectRoutedRemoteActorMultiJvmSpec.scala | 1 + .../remote/NewRemoteActorMultiJvmSpec.scala | 1 + .../RandomRoutedRemoteActorMultiJvmSpec.scala | 1 + ...ndRobinRoutedRemoteActorMultiJvmSpec.scala | 1 + .../akka/remote/RemoteCommunicationSpec.scala | 1 + .../scala/akka/testkit/TestActorRef.scala | 1 + .../test/scala/akka/testkit/AkkaSpec.scala | 1 + .../scala/akka/testkit/TestActorRefSpec.scala | 1 + .../scala/akka/testkit/TestProbeSpec.scala | 1 + .../UntypedCoordinatedIncrementTest.java | 2 +- .../transactor/UntypedTransactorTest.java | 2 +- .../transactor/CoordinatedIncrementSpec.scala | 1 + .../akka/transactor/FickleFriendsSpec.scala | 1 + .../akka/transactor/TransactorSpec.scala | 1 + 53 files changed, 78 insertions(+), 27 deletions(-) diff --git a/akka-actor-tests/src/test/scala/akka/actor/ActorFireForgetRequestReplySpec.scala b/akka-actor-tests/src/test/scala/akka/actor/ActorFireForgetRequestReplySpec.scala index c059497259..8a4d643e29 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/ActorFireForgetRequestReplySpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/ActorFireForgetRequestReplySpec.scala @@ -8,6 +8,7 @@ import akka.testkit._ import org.scalatest.BeforeAndAfterEach import akka.util.duration._ import akka.dispatch.Await +import akka.patterns.ask object ActorFireForgetRequestReplySpec { diff --git a/akka-actor-tests/src/test/scala/akka/actor/ActorLifeCycleSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/ActorLifeCycleSpec.scala index b203ff256f..016b738c45 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/ActorLifeCycleSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/ActorLifeCycleSpec.scala @@ -12,6 +12,7 @@ import akka.testkit._ import akka.util.duration._ import java.util.concurrent.atomic._ import akka.dispatch.Await +import akka.patterns.ask object ActorLifeCycleSpec { diff --git a/akka-actor-tests/src/test/scala/akka/actor/ActorLookupSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/ActorLookupSpec.scala index da6115ef5f..8a990e18ca 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/ActorLookupSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/ActorLookupSpec.scala @@ -6,6 +6,7 @@ package akka.actor import akka.testkit._ import akka.util.duration._ import akka.dispatch.Await +import akka.patterns.ask object ActorLookupSpec { diff --git a/akka-actor-tests/src/test/scala/akka/actor/ActorRefSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/ActorRefSpec.scala index ceea20b2c7..a78a99a79b 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/ActorRefSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/ActorRefSpec.scala @@ -15,6 +15,7 @@ import akka.util.ReflectiveAccess import akka.serialization.Serialization import java.util.concurrent.{ CountDownLatch, TimeUnit } import akka.dispatch.{ Await, DefaultPromise, Promise, Future } +import akka.patterns.ask object ActorRefSpec { diff --git a/akka-actor-tests/src/test/scala/akka/actor/ActorTimeoutSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/ActorTimeoutSpec.scala index 038e3fc9f1..1c9a7e67d6 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/ActorTimeoutSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/ActorTimeoutSpec.scala @@ -10,6 +10,7 @@ import akka.testkit.DefaultTimeout import java.util.concurrent.TimeoutException import akka.dispatch.Await import akka.util.Timeout +import akka.patterns.ask @org.junit.runner.RunWith(classOf[org.scalatest.junit.JUnitRunner]) class ActorTimeoutSpec extends AkkaSpec with BeforeAndAfterAll with DefaultTimeout { diff --git a/akka-actor-tests/src/test/scala/akka/actor/DeathWatchSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/DeathWatchSpec.scala index 30828c1014..1a9c84ecd9 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/DeathWatchSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/DeathWatchSpec.scala @@ -8,6 +8,7 @@ import akka.testkit._ import akka.util.duration._ import java.util.concurrent.atomic._ import akka.dispatch.Await +import akka.patterns.ask @org.junit.runner.RunWith(classOf[org.scalatest.junit.JUnitRunner]) class LocalDeathWatchSpec extends AkkaSpec with ImplicitSender with DefaultTimeout with DeathWatchSpec diff --git a/akka-actor-tests/src/test/scala/akka/actor/ForwardActorSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/ForwardActorSpec.scala index 12b0c796f6..10df9d2218 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/ForwardActorSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/ForwardActorSpec.scala @@ -9,6 +9,7 @@ import akka.util.duration._ import Actor._ import akka.util.Duration import akka.dispatch.Await +import akka.patterns.ask object ForwardActorSpec { val ExpectedMessage = "FOO" diff --git a/akka-actor-tests/src/test/scala/akka/actor/IOActor.scala b/akka-actor-tests/src/test/scala/akka/actor/IOActor.scala index 757acb1fd0..aaa86e9c3e 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/IOActor.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/IOActor.scala @@ -11,6 +11,7 @@ import akka.util.cps._ import scala.util.continuations._ import akka.testkit._ import akka.dispatch.{ Await, Future } +import akka.patterns.ask object IOActorSpec { import IO._ diff --git a/akka-actor-tests/src/test/scala/akka/actor/RestartStrategySpec.scala b/akka-actor-tests/src/test/scala/akka/actor/RestartStrategySpec.scala index b627046052..0730b8de7c 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/RestartStrategySpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/RestartStrategySpec.scala @@ -14,6 +14,7 @@ import akka.testkit.AkkaSpec import akka.testkit.DefaultTimeout import akka.testkit.TestLatch import akka.util.duration._ +import akka.patterns.ask @org.junit.runner.RunWith(classOf[org.scalatest.junit.JUnitRunner]) class RestartStrategySpec extends AkkaSpec with DefaultTimeout { diff --git a/akka-actor-tests/src/test/scala/akka/actor/SchedulerSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/SchedulerSpec.scala index ba06a90023..1269558cf9 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/SchedulerSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/SchedulerSpec.scala @@ -8,6 +8,7 @@ import java.util.concurrent.{ CountDownLatch, ConcurrentLinkedQueue, TimeUnit } import akka.testkit.DefaultTimeout import akka.testkit.TestLatch import akka.dispatch.Await +import akka.patterns.ask @org.junit.runner.RunWith(classOf[org.scalatest.junit.JUnitRunner]) class SchedulerSpec extends AkkaSpec with BeforeAndAfterEach with DefaultTimeout { diff --git a/akka-actor-tests/src/test/scala/akka/actor/SupervisorHierarchySpec.scala b/akka-actor-tests/src/test/scala/akka/actor/SupervisorHierarchySpec.scala index fb34e2345b..88139f97f8 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/SupervisorHierarchySpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/SupervisorHierarchySpec.scala @@ -8,6 +8,7 @@ import akka.testkit._ import java.util.concurrent.{ TimeUnit, CountDownLatch } import akka.dispatch.Await +import akka.patterns.ask object SupervisorHierarchySpec { class FireWorkerException(msg: String) extends Exception(msg) diff --git a/akka-actor-tests/src/test/scala/akka/actor/SupervisorMiscSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/SupervisorMiscSpec.scala index 653342c193..8b32f76e49 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/SupervisorMiscSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/SupervisorMiscSpec.scala @@ -8,6 +8,7 @@ import akka.dispatch.{ PinnedDispatcher, Dispatchers, Await } import java.util.concurrent.{ TimeUnit, CountDownLatch } import akka.testkit.AkkaSpec import akka.testkit.DefaultTimeout +import akka.patterns.ask object SupervisorMiscSpec { val config = """ diff --git a/akka-actor-tests/src/test/scala/akka/actor/SupervisorSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/SupervisorSpec.scala index e68e6f3906..8405e29e8e 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/SupervisorSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/SupervisorSpec.scala @@ -11,6 +11,7 @@ import akka.testkit.TestEvent._ import akka.testkit._ import java.util.concurrent.atomic.AtomicInteger import akka.dispatch.Await +import akka.patterns.ask object SupervisorSpec { val Timeout = 5 seconds diff --git a/akka-actor-tests/src/test/scala/akka/actor/SupervisorTreeSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/SupervisorTreeSpec.scala index 3985f6ea48..6ebca690a7 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/SupervisorTreeSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/SupervisorTreeSpec.scala @@ -12,6 +12,7 @@ import akka.testkit.AkkaSpec import akka.testkit.ImplicitSender import akka.testkit.DefaultTimeout import akka.dispatch.{ Await, Dispatchers } +import akka.patterns.ask @org.junit.runner.RunWith(classOf[org.scalatest.junit.JUnitRunner]) class SupervisorTreeSpec extends AkkaSpec with ImplicitSender with DefaultTimeout { diff --git a/akka-actor-tests/src/test/scala/akka/actor/Ticket669Spec.scala b/akka-actor-tests/src/test/scala/akka/actor/Ticket669Spec.scala index 3b5f29c950..f3a0784da2 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/Ticket669Spec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/Ticket669Spec.scala @@ -11,6 +11,7 @@ import akka.testkit.AkkaSpec import akka.testkit.ImplicitSender import akka.testkit.DefaultTimeout import akka.dispatch.Await +import akka.patterns.ask @org.junit.runner.RunWith(classOf[org.scalatest.junit.JUnitRunner]) class Ticket669Spec extends AkkaSpec with BeforeAndAfterAll with ImplicitSender with DefaultTimeout { diff --git a/akka-actor-tests/src/test/scala/akka/actor/TypedActorSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/TypedActorSpec.scala index 6a6500b131..7cde57720c 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/TypedActorSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/TypedActorSpec.scala @@ -18,6 +18,7 @@ import java.util.concurrent.{ TimeUnit, CountDownLatch } import akka.japi.{ Creator, Option ⇒ JOption } import akka.testkit.DefaultTimeout import akka.dispatch.{ Await, Dispatchers, Future, Promise } +import akka.patterns.ask object TypedActorSpec { diff --git a/akka-actor-tests/src/test/scala/akka/actor/dispatch/ActorModelSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/dispatch/ActorModelSpec.scala index 9debbd053c..c242617753 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/dispatch/ActorModelSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/dispatch/ActorModelSpec.scala @@ -20,6 +20,7 @@ import akka.util.duration._ import akka.event.Logging.Error import com.typesafe.config.Config import akka.util.Duration +import akka.patterns.ask object ActorModelSpec { diff --git a/akka-actor-tests/src/test/scala/akka/actor/dispatch/DispatcherActorSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/dispatch/DispatcherActorSpec.scala index d75bad30c6..1160883e09 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/dispatch/DispatcherActorSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/dispatch/DispatcherActorSpec.scala @@ -8,6 +8,7 @@ import akka.util.Duration import akka.util.duration._ import akka.testkit.DefaultTimeout import akka.dispatch.{ Await, PinnedDispatcher, Dispatchers, Dispatcher } +import akka.patterns.ask object DispatcherActorSpec { val config = """ diff --git a/akka-actor-tests/src/test/scala/akka/actor/dispatch/PinnedActorSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/dispatch/PinnedActorSpec.scala index 6ac18f9947..4ddcb8ba12 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/dispatch/PinnedActorSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/dispatch/PinnedActorSpec.scala @@ -7,6 +7,7 @@ import akka.actor.{ Props, Actor } import akka.testkit.AkkaSpec import org.scalatest.BeforeAndAfterEach import akka.dispatch.{ Await, PinnedDispatcher, Dispatchers } +import akka.patterns.ask object PinnedActorSpec { val config = """ diff --git a/akka-actor-tests/src/test/scala/akka/dataflow/Future2Actor.scala b/akka-actor-tests/src/test/scala/akka/dataflow/Future2Actor.scala index 5d24b9678f..48992a5ee7 100644 --- a/akka-actor-tests/src/test/scala/akka/dataflow/Future2Actor.scala +++ b/akka-actor-tests/src/test/scala/akka/dataflow/Future2Actor.scala @@ -9,6 +9,7 @@ import akka.actor.future2actor import akka.util.duration._ import akka.testkit.AkkaSpec import akka.testkit.DefaultTimeout +import akka.patterns.ask class Future2ActorSpec extends AkkaSpec with DefaultTimeout { diff --git a/akka-actor-tests/src/test/scala/akka/dispatch/FutureSpec.scala b/akka-actor-tests/src/test/scala/akka/dispatch/FutureSpec.scala index 4fbb67fbb4..c874ea68b7 100644 --- a/akka-actor-tests/src/test/scala/akka/dispatch/FutureSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/dispatch/FutureSpec.scala @@ -16,6 +16,7 @@ import akka.testkit.DefaultTimeout import akka.testkit.TestLatch import java.util.concurrent.{ TimeoutException, TimeUnit, CountDownLatch } import scala.runtime.NonLocalReturnControl +import akka.patterns.ask object FutureSpec { class TestActor extends Actor { diff --git a/akka-actor-tests/src/test/scala/akka/dispatch/PriorityDispatcherSpec.scala b/akka-actor-tests/src/test/scala/akka/dispatch/PriorityDispatcherSpec.scala index ec6aab48be..82fcc372fa 100644 --- a/akka-actor-tests/src/test/scala/akka/dispatch/PriorityDispatcherSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/dispatch/PriorityDispatcherSpec.scala @@ -2,7 +2,7 @@ package akka.dispatch import akka.actor.{ Props, LocalActorRef, Actor } import akka.testkit.AkkaSpec -import akka.util.Duration +import akka.patterns.ask import akka.util.duration._ import akka.testkit.DefaultTimeout import com.typesafe.config.Config diff --git a/akka-actor-tests/src/test/scala/akka/routing/ActorPoolSpec.scala b/akka-actor-tests/src/test/scala/akka/routing/ActorPoolSpec.scala index f18fd2e5e1..bfdb168156 100644 --- a/akka-actor-tests/src/test/scala/akka/routing/ActorPoolSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/routing/ActorPoolSpec.scala @@ -6,6 +6,7 @@ import akka.util.duration._ import java.util.concurrent.atomic.{ AtomicBoolean, AtomicInteger } import akka.testkit.AkkaSpec import akka.dispatch.{ Await, Promise, Future } +import akka.patterns.ask object ActorPoolSpec { diff --git a/akka-actor-tests/src/test/scala/akka/routing/ConfiguredLocalRoutingSpec.scala b/akka-actor-tests/src/test/scala/akka/routing/ConfiguredLocalRoutingSpec.scala index dd4e45f5cb..2d4a4be1c2 100644 --- a/akka-actor-tests/src/test/scala/akka/routing/ConfiguredLocalRoutingSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/routing/ConfiguredLocalRoutingSpec.scala @@ -6,6 +6,7 @@ import java.util.concurrent.atomic.AtomicInteger import akka.testkit._ import akka.util.duration._ import akka.dispatch.Await +import akka.patterns.ask @org.junit.runner.RunWith(classOf[org.scalatest.junit.JUnitRunner]) class ConfiguredLocalRoutingSpec extends AkkaSpec with DefaultTimeout with ImplicitSender { diff --git a/akka-actor-tests/src/test/scala/akka/routing/RoutingSpec.scala b/akka-actor-tests/src/test/scala/akka/routing/RoutingSpec.scala index fb2aa50372..dff790f50f 100644 --- a/akka-actor-tests/src/test/scala/akka/routing/RoutingSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/routing/RoutingSpec.scala @@ -12,6 +12,7 @@ import akka.dispatch.Await import akka.util.Duration import akka.config.ConfigurationException import com.typesafe.config.ConfigFactory +import akka.patterns.ask object RoutingSpec { diff --git a/akka-actor-tests/src/test/scala/akka/serialization/SerializeSpec.scala b/akka-actor-tests/src/test/scala/akka/serialization/SerializeSpec.scala index 51dc26d6c5..cfec55413d 100644 --- a/akka-actor-tests/src/test/scala/akka/serialization/SerializeSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/serialization/SerializeSpec.scala @@ -13,6 +13,7 @@ import akka.util.Timeout import akka.util.duration._ import scala.reflect.BeanInfo import com.google.protobuf.Message +import akka.patterns.ask class ProtobufSerializer extends Serializer { val ARRAY_OF_BYTE_ARRAY = Array[Class[_]](classOf[Array[Byte]]) diff --git a/akka-actor-tests/src/test/scala/akka/ticket/Ticket703Spec.scala b/akka-actor-tests/src/test/scala/akka/ticket/Ticket703Spec.scala index f51beb7617..63367ff508 100644 --- a/akka-actor-tests/src/test/scala/akka/ticket/Ticket703Spec.scala +++ b/akka-actor-tests/src/test/scala/akka/ticket/Ticket703Spec.scala @@ -5,6 +5,7 @@ import akka.routing._ import akka.testkit.AkkaSpec import akka.dispatch.Await import akka.util.duration._ +import akka.patterns.ask @org.junit.runner.RunWith(classOf[org.scalatest.junit.JUnitRunner]) class Ticket703Spec extends AkkaSpec { diff --git a/akka-actor/src/main/scala/akka/actor/package.scala b/akka-actor/src/main/scala/akka/actor/package.scala index f67a3bb1fa..acfbb19e5d 100644 --- a/akka-actor/src/main/scala/akka/actor/package.scala +++ b/akka-actor/src/main/scala/akka/actor/package.scala @@ -149,10 +149,13 @@ object Patterns { import akka.actor.ActorRef import akka.dispatch.Future - import akka.patterns.{ ask => actorRef2Askable } + import akka.patterns.{ ask ⇒ actorRef2Askable } import akka.util.Timeout - def ask(actor: ActorRef, message: Any, timeout: Timeout): Future[Any] = + def ask(actor: ActorRef, message: Any)(implicit timeout: Timeout): Future[Any] = + actorRef2Askable(actor).?(message) + + def ask(actor: ActorRef, message: Any, timeout: Timeout)(implicit ignore: Int = 0): Future[Any] = actorRef2Askable(actor).?(message)(timeout) def ask(actor: ActorRef, message: Any, timeoutMillis: Long): Future[Any] = diff --git a/akka-agent/src/main/scala/akka/agent/Agent.scala b/akka-agent/src/main/scala/akka/agent/Agent.scala index dffd8df1cc..8337c0f64b 100644 --- a/akka-agent/src/main/scala/akka/agent/Agent.scala +++ b/akka-agent/src/main/scala/akka/agent/Agent.scala @@ -7,6 +7,7 @@ package akka.agent import akka.actor._ import akka.japi.{ Function ⇒ JFunc, Procedure ⇒ JProc } import akka.dispatch._ +import akka.patterns.ask import akka.util.Timeout import scala.concurrent.stm._ diff --git a/akka-docs/java/code/akka/docs/actor/FaultHandlingTestBase.java b/akka-docs/java/code/akka/docs/actor/FaultHandlingTestBase.java index 1bc3b40c4b..f67347b2af 100644 --- a/akka-docs/java/code/akka/docs/actor/FaultHandlingTestBase.java +++ b/akka-docs/java/code/akka/docs/actor/FaultHandlingTestBase.java @@ -13,7 +13,7 @@ import akka.actor.Props; import akka.actor.Terminated; import akka.actor.UntypedActor; import akka.dispatch.Await; -import static akka.dispatch.Futures.ask; +import static akka.Patterns.ask; import akka.util.Duration; import akka.testkit.AkkaSpec; import akka.testkit.TestProbe; diff --git a/akka-docs/java/code/akka/docs/actor/UntypedActorDocTestBase.java b/akka-docs/java/code/akka/docs/actor/UntypedActorDocTestBase.java index be164aa850..4944f817f5 100644 --- a/akka-docs/java/code/akka/docs/actor/UntypedActorDocTestBase.java +++ b/akka-docs/java/code/akka/docs/actor/UntypedActorDocTestBase.java @@ -38,6 +38,7 @@ import org.junit.Test; import scala.Option; import java.lang.Object; import java.util.concurrent.TimeUnit; +import akka.Patterns; import static org.junit.Assert.*; @@ -118,7 +119,7 @@ public class UntypedActorDocTestBase { }), "myactor"); //#using-ask - Future future = Futures.ask(myActor, "Hello", 1000); + Future future = Patterns.ask(myActor, "Hello", 1000); Object result = Await.result(future, Duration.create(1, TimeUnit.SECONDS)); //#using-ask system.shutdown(); @@ -170,7 +171,7 @@ public class UntypedActorDocTestBase { public void useWatch() { ActorSystem system = ActorSystem.create("MySystem"); ActorRef myActor = system.actorOf(new Props(WatchActor.class)); - Future future = myActor.ask("kill", 1000); + Future future = Patterns.ask(myActor, "kill", 1000); assert Await.result(future, Duration.parse("1 second")).equals("finished"); system.shutdown(); } diff --git a/akka-docs/java/code/akka/docs/future/FutureDocTestBase.java b/akka-docs/java/code/akka/docs/future/FutureDocTestBase.java index 956e72eab9..dd10afd165 100644 --- a/akka-docs/java/code/akka/docs/future/FutureDocTestBase.java +++ b/akka-docs/java/code/akka/docs/future/FutureDocTestBase.java @@ -55,6 +55,7 @@ import akka.actor.UntypedActor; import akka.actor.ActorRef; import akka.actor.Props; import akka.dispatch.Futures; +import akka.Patterns; import static org.junit.Assert.*; @@ -78,7 +79,7 @@ public class FutureDocTestBase { String msg = "hello"; //#ask-blocking Timeout timeout = system.settings().ActorTimeout(); - Future future = Futures.ask(actor, msg, timeout); + Future future = Patterns.ask(actor, msg, timeout); String result = (String) Await.result(future, timeout.duration()); //#ask-blocking assertEquals("HELLO", result); diff --git a/akka-docs/java/code/akka/docs/transactor/TransactorDocTest.java b/akka-docs/java/code/akka/docs/transactor/TransactorDocTest.java index 75fa92cd8f..bb2f069dd0 100644 --- a/akka-docs/java/code/akka/docs/transactor/TransactorDocTest.java +++ b/akka-docs/java/code/akka/docs/transactor/TransactorDocTest.java @@ -10,7 +10,7 @@ import org.junit.Test; //#imports import akka.actor.*; import akka.dispatch.Await; -import static akka.dispatch.Futures.ask; +import static akka.Patterns.ask; import akka.transactor.Coordinated; import akka.util.Duration; import akka.util.Timeout; diff --git a/akka-docs/scala/code/akka/docs/actor/ActorDocSpec.scala b/akka-docs/scala/code/akka/docs/actor/ActorDocSpec.scala index 3907e6cf47..f804e29bac 100644 --- a/akka-docs/scala/code/akka/docs/actor/ActorDocSpec.scala +++ b/akka-docs/scala/code/akka/docs/actor/ActorDocSpec.scala @@ -8,7 +8,7 @@ import akka.actor.Actor import akka.actor.Props import akka.event.Logging import akka.dispatch.Future -import akka.dispatch.Futures +import akka.Patterns //#imports1 @@ -230,10 +230,10 @@ class ActorDocSpec extends AkkaSpec(Map("akka.loglevel" -> "INFO")) { val myActor = system.actorOf(Props(new MyActor), name = "myactor") implicit val timeout = system.settings.ActorTimeout - val future = Futures.ask(myActor, "hello") + val future = Patterns.ask(myActor, "hello") for (x ← future) println(x) //Prints "hello" - val result: Future[Int] = for (x ← Futures.ask(myActor, 3).mapTo[Int]) yield { 2 * x } + val result: Future[Int] = for (x ← Patterns.ask(myActor, 3).mapTo[Int]) yield { 2 * x } //#using-ask system.stop(myActor) @@ -244,6 +244,7 @@ class ActorDocSpec extends AkkaSpec(Map("akka.loglevel" -> "INFO")) { //#using-implicit-timeout import akka.util.duration._ import akka.util.Timeout + import akka.patterns.ask implicit val timeout = Timeout(500 millis) val future = myActor ? "hello" //#using-implicit-timeout @@ -255,6 +256,7 @@ class ActorDocSpec extends AkkaSpec(Map("akka.loglevel" -> "INFO")) { val myActor = system.actorOf(Props(new FirstActor)) //#using-explicit-timeout import akka.util.duration._ + import akka.patterns.ask val future = myActor ? ("hello", timeout = 500 millis) //#using-explicit-timeout Await.result(future, 500 millis) must be("hello") diff --git a/akka-docs/scala/code/akka/docs/future/FutureDocSpec.scala b/akka-docs/scala/code/akka/docs/future/FutureDocSpec.scala index bb96a4e3a0..f65f8224db 100644 --- a/akka-docs/scala/code/akka/docs/future/FutureDocSpec.scala +++ b/akka-docs/scala/code/akka/docs/future/FutureDocSpec.scala @@ -10,10 +10,10 @@ import akka.actor.Actor import akka.actor.Props import akka.actor.Status.Failure import akka.dispatch.Future -import akka.dispatch.Futures import akka.dispatch.Await import akka.util.duration._ import akka.dispatch.Promise +import akka.Patterns object FutureDocSpec { @@ -47,7 +47,7 @@ class FutureDocSpec extends AkkaSpec { import akka.dispatch.Await implicit val timeout = system.settings.ActorTimeout - val future = Futures.ask(actor, msg) + val future = Patterns.ask(actor, msg) val result = Await.result(future, timeout.duration).asInstanceOf[String] //#ask-blocking result must be("HELLO") @@ -60,7 +60,7 @@ class FutureDocSpec extends AkkaSpec { //#map-to import akka.dispatch.Future - val future: Future[String] = Futures.ask(actor, msg).mapTo[String] + val future: Future[String] = Patterns.ask(actor, msg).mapTo[String] //#map-to Await.result(future, timeout.duration) must be("HELLO") } @@ -150,13 +150,13 @@ class FutureDocSpec extends AkkaSpec { import akka.dispatch.Await //#composing-wrong - val f1 = Futures.ask(actor1, msg1) - val f2 = Futures.ask(actor2, msg2) + val f1 = Patterns.ask(actor1, msg1) + val f2 = Patterns.ask(actor2, msg2) val a = Await.result(f1, 1 second).asInstanceOf[Int] val b = Await.result(f2, 1 second).asInstanceOf[Int] - val f3 = Futures.ask(actor3, (a + b)) + val f3 = Patterns.ask(actor3, (a + b)) val result = Await.result(f3, 1 second).asInstanceOf[Int] //#composing-wrong @@ -173,13 +173,13 @@ class FutureDocSpec extends AkkaSpec { import akka.dispatch.Await //#composing - val f1 = Futures.ask(actor1, msg1) - val f2 = Futures.ask(actor2, msg2) + val f1 = Patterns.ask(actor1, msg1) + val f2 = Patterns.ask(actor2, msg2) val f3 = for { a ← f1.mapTo[Int] b ← f2.mapTo[Int] - c ← Futures.ask(actor3, (a + b)).mapTo[Int] + c ← Patterns.ask(actor3, (a + b)).mapTo[Int] } yield c val result = Await.result(f3, 1 second).asInstanceOf[Int] @@ -192,7 +192,7 @@ class FutureDocSpec extends AkkaSpec { val oddActor = system.actorOf(Props[OddActor]) //#sequence-ask // oddActor returns odd numbers sequentially from 1 as a List[Future[Int]] - val listOfFutures = List.fill(100)(Futures.ask(oddActor, GetNext).mapTo[Int]) + val listOfFutures = List.fill(100)(Patterns.ask(oddActor, GetNext).mapTo[Int]) // now we have a Future[List[Int]] val futureList = Future.sequence(listOfFutures) @@ -240,7 +240,7 @@ class FutureDocSpec extends AkkaSpec { val actor = system.actorOf(Props[MyActor]) val msg1 = -1 //#recover - val future = Futures.ask(actor, msg1) recover { + val future = Patterns.ask(actor, msg1) recover { case e: ArithmeticException ⇒ 0 } //#recover diff --git a/akka-docs/scala/code/akka/docs/routing/RouterTypeExample.scala b/akka-docs/scala/code/akka/docs/routing/RouterTypeExample.scala index c366c011c1..bc3f370f5b 100644 --- a/akka-docs/scala/code/akka/docs/routing/RouterTypeExample.scala +++ b/akka-docs/scala/code/akka/docs/routing/RouterTypeExample.scala @@ -7,7 +7,8 @@ import akka.routing.{ ScatterGatherFirstCompletedRouter, BroadcastRouter, Random import annotation.tailrec import akka.actor.{ Props, Actor } import akka.util.duration._ -import akka.dispatch.{ Futures, Await } +import akka.dispatch.Await +import akka.patterns.ask case class FibonacciNumber(nbr: Int) @@ -71,7 +72,7 @@ class ParentActor extends Actor { Props[FibonacciActor].withRouter(ScatterGatherFirstCompletedRouter(within = 2 seconds)), "router") implicit val timeout = context.system.settings.ActorTimeout - val futureResult = Futures.ask(scatterGatherFirstCompletedRouter, FibonacciNumber(10)) + val futureResult = scatterGatherFirstCompletedRouter ? FibonacciNumber(10) val result = Await.result(futureResult, timeout.duration) //#scatterGatherFirstCompletedRouter println("The result of calculating Fibonacci for 10 is %d".format(result)) diff --git a/akka-docs/scala/code/akka/docs/testkit/TestkitDocSpec.scala b/akka-docs/scala/code/akka/docs/testkit/TestkitDocSpec.scala index c646f9ea54..b3ff8d2e05 100644 --- a/akka-docs/scala/code/akka/docs/testkit/TestkitDocSpec.scala +++ b/akka-docs/scala/code/akka/docs/testkit/TestkitDocSpec.scala @@ -120,6 +120,7 @@ class TestkitDocSpec extends AkkaSpec with DefaultTimeout with ImplicitSender { import akka.testkit.TestActorRef import akka.util.duration._ import akka.dispatch.Await + import akka.patterns.ask val actorRef = TestActorRef(new MyActor) // hypothetical message stimulating a '42' answer @@ -203,9 +204,10 @@ class TestkitDocSpec extends AkkaSpec with DefaultTimeout with ImplicitSender { "demonstrate probe reply" in { import akka.testkit.TestProbe import akka.util.duration._ + import akka.patterns.ask //#test-probe-reply val probe = TestProbe() - val future = Futures.ask(probe.ref, "hello") + val future = probe.ref ? "hello" probe.expectMsg(0 millis, "hello") // TestActor runs on CallingThreadDispatcher probe.sender ! "world" assert(future.isCompleted && future.value == Some(Right("world"))) diff --git a/akka-docs/scala/code/akka/docs/transactor/TransactorDocSpec.scala b/akka-docs/scala/code/akka/docs/transactor/TransactorDocSpec.scala index 246ea0a352..2cde9c9890 100644 --- a/akka-docs/scala/code/akka/docs/transactor/TransactorDocSpec.scala +++ b/akka-docs/scala/code/akka/docs/transactor/TransactorDocSpec.scala @@ -141,6 +141,7 @@ class TransactorDocSpec extends AkkaSpec { import akka.dispatch.Await import akka.util.duration._ import akka.util.Timeout + import akka.patterns.ask val system = ActorSystem("app") diff --git a/akka-remote/src/main/scala/akka/remote/Gossiper.scala b/akka-remote/src/main/scala/akka/remote/Gossiper.scala index a12e5ecab1..3ff54b5efe 100644 --- a/akka-remote/src/main/scala/akka/remote/Gossiper.scala +++ b/akka-remote/src/main/scala/akka/remote/Gossiper.scala @@ -22,6 +22,7 @@ import scala.annotation.tailrec import com.google.protobuf.ByteString import java.util.concurrent.TimeoutException import akka.dispatch.Await +import akka.patterns.ask /** * Interface for node membership change listener. diff --git a/akka-remote/src/multi-jvm/scala/akka/remote/DirectRoutedRemoteActorMultiJvmSpec.scala b/akka-remote/src/multi-jvm/scala/akka/remote/DirectRoutedRemoteActorMultiJvmSpec.scala index 1b7a561cda..58c52d8971 100644 --- a/akka-remote/src/multi-jvm/scala/akka/remote/DirectRoutedRemoteActorMultiJvmSpec.scala +++ b/akka-remote/src/multi-jvm/scala/akka/remote/DirectRoutedRemoteActorMultiJvmSpec.scala @@ -5,6 +5,7 @@ import akka.routing._ import akka.actor.{ Actor, Props } import akka.testkit._ import akka.dispatch.Await +import akka.patterns.ask object DirectRoutedRemoteActorMultiJvmSpec extends AbstractRemoteActorMultiJvmSpec { override def NrOfNodes = 2 diff --git a/akka-remote/src/multi-jvm/scala/akka/remote/NewRemoteActorMultiJvmSpec.scala b/akka-remote/src/multi-jvm/scala/akka/remote/NewRemoteActorMultiJvmSpec.scala index f7a02c3988..cc8f62552c 100644 --- a/akka-remote/src/multi-jvm/scala/akka/remote/NewRemoteActorMultiJvmSpec.scala +++ b/akka-remote/src/multi-jvm/scala/akka/remote/NewRemoteActorMultiJvmSpec.scala @@ -6,6 +6,7 @@ import akka.routing._ import akka.testkit._ import akka.util.duration._ import akka.dispatch.Await +import akka.patterns.ask object NewRemoteActorMultiJvmSpec extends AbstractRemoteActorMultiJvmSpec { override def NrOfNodes = 2 diff --git a/akka-remote/src/multi-jvm/scala/akka/remote/RandomRoutedRemoteActorMultiJvmSpec.scala b/akka-remote/src/multi-jvm/scala/akka/remote/RandomRoutedRemoteActorMultiJvmSpec.scala index b9440d28b3..d466c014b3 100644 --- a/akka-remote/src/multi-jvm/scala/akka/remote/RandomRoutedRemoteActorMultiJvmSpec.scala +++ b/akka-remote/src/multi-jvm/scala/akka/remote/RandomRoutedRemoteActorMultiJvmSpec.scala @@ -5,6 +5,7 @@ import akka.remote._ import akka.routing._ import akka.testkit.DefaultTimeout import akka.dispatch.Await +import akka.patterns.ask object RandomRoutedRemoteActorMultiJvmSpec extends AbstractRemoteActorMultiJvmSpec { override def NrOfNodes = 4 diff --git a/akka-remote/src/multi-jvm/scala/akka/remote/RoundRobinRoutedRemoteActorMultiJvmSpec.scala b/akka-remote/src/multi-jvm/scala/akka/remote/RoundRobinRoutedRemoteActorMultiJvmSpec.scala index 5b5c6cbf6d..22eb8cd8c3 100644 --- a/akka-remote/src/multi-jvm/scala/akka/remote/RoundRobinRoutedRemoteActorMultiJvmSpec.scala +++ b/akka-remote/src/multi-jvm/scala/akka/remote/RoundRobinRoutedRemoteActorMultiJvmSpec.scala @@ -5,6 +5,7 @@ import akka.remote._ import akka.routing._ import akka.testkit.DefaultTimeout import akka.dispatch.Await +import akka.patterns.ask object RoundRobinRoutedRemoteActorMultiJvmSpec extends AbstractRemoteActorMultiJvmSpec { override def NrOfNodes = 4 diff --git a/akka-remote/src/test/scala/akka/remote/RemoteCommunicationSpec.scala b/akka-remote/src/test/scala/akka/remote/RemoteCommunicationSpec.scala index 0be7c0f361..17068cc351 100644 --- a/akka-remote/src/test/scala/akka/remote/RemoteCommunicationSpec.scala +++ b/akka-remote/src/test/scala/akka/remote/RemoteCommunicationSpec.scala @@ -7,6 +7,7 @@ import akka.testkit._ import akka.actor._ import com.typesafe.config._ import akka.dispatch.Await +import akka.patterns.ask object RemoteCommunicationSpec { class Echo extends Actor { diff --git a/akka-testkit/src/main/scala/akka/testkit/TestActorRef.scala b/akka-testkit/src/main/scala/akka/testkit/TestActorRef.scala index 2d52f21226..01ce145afa 100644 --- a/akka-testkit/src/main/scala/akka/testkit/TestActorRef.scala +++ b/akka-testkit/src/main/scala/akka/testkit/TestActorRef.scala @@ -13,6 +13,7 @@ import java.util.concurrent.atomic.AtomicLong import akka.event.EventStream import scala.collection.immutable.Stack import akka.dispatch._ +import akka.patterns.ask /** * This special ActorRef is exclusively for use during unit testing in a single-threaded environment. Therefore, it diff --git a/akka-testkit/src/test/scala/akka/testkit/AkkaSpec.scala b/akka-testkit/src/test/scala/akka/testkit/AkkaSpec.scala index b98937b126..e47587fc9c 100644 --- a/akka-testkit/src/test/scala/akka/testkit/AkkaSpec.scala +++ b/akka-testkit/src/test/scala/akka/testkit/AkkaSpec.scala @@ -17,6 +17,7 @@ import akka.actor.DeadLetter import java.util.concurrent.TimeoutException import akka.dispatch.{ Await, MessageDispatcher } import akka.dispatch.Dispatchers +import akka.patterns.ask object TimingTest extends Tag("timing") diff --git a/akka-testkit/src/test/scala/akka/testkit/TestActorRefSpec.scala b/akka-testkit/src/test/scala/akka/testkit/TestActorRefSpec.scala index 747a9c90e9..b742165f1d 100644 --- a/akka-testkit/src/test/scala/akka/testkit/TestActorRefSpec.scala +++ b/akka-testkit/src/test/scala/akka/testkit/TestActorRefSpec.scala @@ -10,6 +10,7 @@ import akka.event.Logging.Warning import akka.dispatch.{ Future, Promise, Await } import akka.util.duration._ import akka.actor.ActorSystem +import akka.patterns.ask /** * Test whether TestActorRef behaves as an ActorRef should, besides its own spec. diff --git a/akka-testkit/src/test/scala/akka/testkit/TestProbeSpec.scala b/akka-testkit/src/test/scala/akka/testkit/TestProbeSpec.scala index 4723070299..6a4a9db420 100644 --- a/akka-testkit/src/test/scala/akka/testkit/TestProbeSpec.scala +++ b/akka-testkit/src/test/scala/akka/testkit/TestProbeSpec.scala @@ -6,6 +6,7 @@ import org.scalatest.{ BeforeAndAfterEach, WordSpec } import akka.actor._ import akka.util.duration._ import akka.dispatch.{ Await, Future } +import akka.patterns.ask @org.junit.runner.RunWith(classOf[org.scalatest.junit.JUnitRunner]) class TestProbeSpec extends AkkaSpec with DefaultTimeout { diff --git a/akka-transactor/src/test/java/akka/transactor/UntypedCoordinatedIncrementTest.java b/akka-transactor/src/test/java/akka/transactor/UntypedCoordinatedIncrementTest.java index 267cf261b7..d282a638fc 100644 --- a/akka-transactor/src/test/java/akka/transactor/UntypedCoordinatedIncrementTest.java +++ b/akka-transactor/src/test/java/akka/transactor/UntypedCoordinatedIncrementTest.java @@ -18,7 +18,7 @@ import akka.actor.UntypedActor; import akka.actor.UntypedActorFactory; import akka.dispatch.Await; import akka.dispatch.Future; -import static akka.dispatch.Futures.ask; +import static akka.Patterns.ask; import akka.testkit.AkkaSpec; import akka.testkit.EventFilter; import akka.testkit.ErrorFilter; diff --git a/akka-transactor/src/test/java/akka/transactor/UntypedTransactorTest.java b/akka-transactor/src/test/java/akka/transactor/UntypedTransactorTest.java index 3c80d659cf..2a6e30ea81 100644 --- a/akka-transactor/src/test/java/akka/transactor/UntypedTransactorTest.java +++ b/akka-transactor/src/test/java/akka/transactor/UntypedTransactorTest.java @@ -18,7 +18,7 @@ import akka.actor.UntypedActor; import akka.actor.UntypedActorFactory; import akka.dispatch.Await; import akka.dispatch.Future; -import static akka.dispatch.Futures.ask; +import static akka.Patterns.ask; import akka.testkit.AkkaSpec; import akka.testkit.EventFilter; import akka.testkit.ErrorFilter; diff --git a/akka-transactor/src/test/scala/akka/transactor/CoordinatedIncrementSpec.scala b/akka-transactor/src/test/scala/akka/transactor/CoordinatedIncrementSpec.scala index 47067d3595..2c2e4376e9 100644 --- a/akka-transactor/src/test/scala/akka/transactor/CoordinatedIncrementSpec.scala +++ b/akka-transactor/src/test/scala/akka/transactor/CoordinatedIncrementSpec.scala @@ -12,6 +12,7 @@ import akka.util.duration._ import akka.util.Timeout import akka.testkit._ import scala.concurrent.stm._ +import akka.patterns.ask object CoordinatedIncrement { case class Increment(friends: Seq[ActorRef]) diff --git a/akka-transactor/src/test/scala/akka/transactor/FickleFriendsSpec.scala b/akka-transactor/src/test/scala/akka/transactor/FickleFriendsSpec.scala index 6f4e46de6a..a8e4e1ad0e 100644 --- a/akka-transactor/src/test/scala/akka/transactor/FickleFriendsSpec.scala +++ b/akka-transactor/src/test/scala/akka/transactor/FickleFriendsSpec.scala @@ -15,6 +15,7 @@ import akka.testkit.TestEvent.Mute import scala.concurrent.stm._ import scala.util.Random.{ nextInt ⇒ random } import java.util.concurrent.CountDownLatch +import akka.patterns.ask object FickleFriends { case class FriendlyIncrement(friends: Seq[ActorRef], timeout: Timeout, latch: CountDownLatch) diff --git a/akka-transactor/src/test/scala/akka/transactor/TransactorSpec.scala b/akka-transactor/src/test/scala/akka/transactor/TransactorSpec.scala index db273cdac7..2d5797c97a 100644 --- a/akka-transactor/src/test/scala/akka/transactor/TransactorSpec.scala +++ b/akka-transactor/src/test/scala/akka/transactor/TransactorSpec.scala @@ -10,6 +10,7 @@ import akka.util.duration._ import akka.util.Timeout import akka.testkit._ import scala.concurrent.stm._ +import akka.patterns.ask object TransactorIncrement { case class Increment(friends: Seq[ActorRef], latch: TestLatch) From 9c762dec2062f7a651363a6cc90d8105126d8f35 Mon Sep 17 00:00:00 2001 From: Roland Date: Tue, 17 Jan 2012 17:04:20 +0100 Subject: [PATCH 07/18] =?UTF-8?q?polish=20=E2=80=9Cask=E2=80=9D=20pattern,?= =?UTF-8?q?=20see=20#1581?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - move package objects into their respective package.scala file in the right directories - make implicit conversion as well as explicit facility available under the same name akka.patterns.ask for easy import - revert the logic to produce the Promise for the PromiseActorRef within the ActorRefProvider; supporting wrapping of external Promises does not seem to justify doing needless extra allocations in case of failure - add scaladocs - factor out “def provider” into trait ActorRefWithProvider, as it didn’t feel right attaching this information “by exception” to MinimalActorRef --- .../scala/akka/actor/ForwardActorSpec.scala | 2 +- akka-actor/src/main/scala/akka/Patterns.scala | 71 ++++++++++ .../src/main/scala/akka/actor/ActorRef.scala | 19 ++- .../scala/akka/actor/ActorRefProvider.scala | 23 +--- .../src/main/scala/akka/actor/package.scala | 123 ------------------ .../scala/akka/patterns/AskableActorRef.scala | 84 ++++++++++++ .../main/scala/akka/patterns/package.scala | 70 ++++++++++ .../src/main/scala/akka/routing/Routing.scala | 14 +- .../code/akka/docs/actor/ActorDocSpec.scala | 7 +- .../code/akka/docs/future/FutureDocSpec.scala | 25 ++-- .../akka/remote/RemoteActorRefProvider.scala | 6 +- 11 files changed, 268 insertions(+), 176 deletions(-) create mode 100644 akka-actor/src/main/scala/akka/Patterns.scala create mode 100644 akka-actor/src/main/scala/akka/patterns/AskableActorRef.scala create mode 100644 akka-actor/src/main/scala/akka/patterns/package.scala diff --git a/akka-actor-tests/src/test/scala/akka/actor/ForwardActorSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/ForwardActorSpec.scala index 10df9d2218..a019b4afb3 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/ForwardActorSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/ForwardActorSpec.scala @@ -47,7 +47,7 @@ class ForwardActorSpec extends AkkaSpec { "forward actor reference when invoking forward on ask" in { val chain = createForwardingChain(system) - chain.ask(ExpectedMessage, 5000) onSuccess { case ExpectedMessage ⇒ testActor ! ExpectedMessage } + chain.ask(ExpectedMessage)(5000) onSuccess { case ExpectedMessage ⇒ testActor ! ExpectedMessage } expectMsg(5 seconds, ExpectedMessage) } } diff --git a/akka-actor/src/main/scala/akka/Patterns.scala b/akka-actor/src/main/scala/akka/Patterns.scala new file mode 100644 index 0000000000..7650c4077f --- /dev/null +++ b/akka-actor/src/main/scala/akka/Patterns.scala @@ -0,0 +1,71 @@ +/** + * Copyright (C) 2009-2011 Typesafe Inc. + */ +package akka + +object Patterns { + import akka.actor.ActorRef + import akka.dispatch.Future + import akka.patterns.{ ask ⇒ scalaAsk } + import akka.util.Timeout + + /** + * Sends a message asynchronously and returns a [[akka.dispatch.Future]] + * holding the eventual reply message; this means that the target actor + * needs to send the result to the `sender` reference provided. The Future + * will be completed with an [[akka.actor.AskTimeoutException]] after the + * given timeout has expired; this is independent from any timeout applied + * while awaiting a result for this future (i.e. in + * `Await.result(..., timeout)`). + * + * Warning: + * When using future callbacks, inside actors you need to carefully avoid closing over + * the containing actor’s object, i.e. do not call methods or access mutable state + * on the enclosing actor from within the callback. This would break the actor + * encapsulation and may introduce synchronization bugs and race conditions because + * the callback will be scheduled concurrently to the enclosing actor. Unfortunately + * there is not yet a way to detect these illegal accesses at compile time. + * + * Recommended usage: + * + * {{{ + * final Future f = Patterns.ask(worker, request, timeout); + * f.onSuccess(new Procedure() { + * public void apply(Object o) { + * nextActor.tell(new EnrichedResult(request, o)); + * } + * }); + * }}} + */ + def ask(actor: ActorRef, message: Any, timeout: Timeout): Future[AnyRef] = scalaAsk(actor, message)(timeout).asInstanceOf[Future[AnyRef]] + + /** + * Sends a message asynchronously and returns a [[akka.dispatch.Future]] + * holding the eventual reply message; this means that the target actor + * needs to send the result to the `sender` reference provided. The Future + * will be completed with an [[akka.actor.AskTimeoutException]] after the + * given timeout has expired; this is independent from any timeout applied + * while awaiting a result for this future (i.e. in + * `Await.result(..., timeout)`). + * + * Warning: + * When using future callbacks, inside actors you need to carefully avoid closing over + * the containing actor’s object, i.e. do not call methods or access mutable state + * on the enclosing actor from within the callback. This would break the actor + * encapsulation and may introduce synchronization bugs and race conditions because + * the callback will be scheduled concurrently to the enclosing actor. Unfortunately + * there is not yet a way to detect these illegal accesses at compile time. + * + * Recommended usage: + * + * {{{ + * final Future f = Patterns.ask(worker, request, timeout); + * f.onSuccess(new Procedure() { + * public void apply(Object o) { + * nextActor.tell(new EnrichedResult(request, o)); + * } + * }); + * }}} + */ + def ask(actor: ActorRef, message: Any, timeoutMillis: Long): Future[AnyRef] = scalaAsk(actor, message)(new Timeout(timeoutMillis)).asInstanceOf[Future[AnyRef]] +} \ No newline at end of file diff --git a/akka-actor/src/main/scala/akka/actor/ActorRef.scala b/akka-actor/src/main/scala/akka/actor/ActorRef.scala index b689aa5370..e7c03e8ae0 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorRef.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorRef.scala @@ -167,6 +167,13 @@ trait LocalRef extends ActorRefScope { final def isLocal = true } +/** + * Trait for matching on ActorRefs which have access to a provider; this is used in akka.patterns.ask. + */ +trait ActorRefWithProvider { this: InternalActorRef ⇒ + def provider: ActorRefProvider +} + /** * Internal trait for assembling all the functionality needed internally on * ActorRefs. NOTE THAT THIS IS NOT A STABLE EXTERNAL INTERFACE! @@ -180,7 +187,6 @@ private[akka] abstract class InternalActorRef extends ActorRef with ScalaActorRe def stop(): Unit def sendSystemMessage(message: SystemMessage): Unit def getParent: InternalActorRef - def provider: ActorRefProvider /** * Obtain ActorRef by possibly traversing the actor tree or looking it up at * some provider-specific location. This method shall return the end result, @@ -212,7 +218,7 @@ private[akka] class LocalActorRef private[akka] ( val systemService: Boolean = false, _receiveTimeout: Option[Duration] = None, _hotswap: Stack[PartialFunction[Any, Unit]] = Props.noHotSwap) - extends InternalActorRef with LocalRef { + extends InternalActorRef with LocalRef with ActorRefWithProvider { /* * actorCell.start() publishes actorCell & this to the dispatcher, which @@ -341,8 +347,7 @@ case class SerializedActorRef(path: String) { trait MinimalActorRef extends InternalActorRef with LocalRef { def getParent: InternalActorRef = Nobody - def provider: ActorRefProvider = - throw new UnsupportedOperationException("Not supported for [%s]".format(getClass.getName)) + def getChild(names: Iterator[String]): InternalActorRef = { val dropped = names.dropWhile(_.isEmpty) if (dropped.isEmpty) this @@ -466,10 +471,14 @@ class AskTimeoutException(message: String, cause: Throwable) extends TimeoutExce def this(message: String) = this(message, null: Throwable) } +/** + * Akka private optimized representation of the temporary actor spawned to + * receive the reply to an "ask" operation. + */ private[akka] final class PromiseActorRef( val path: ActorPath, override val getParent: InternalActorRef, - private final val result: Promise[Any], + val result: Promise[Any], val deathWatch: DeathWatch) extends MinimalActorRef { final val running = new AtomicBoolean(true) diff --git a/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala b/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala index 6af8c36198..4408f7562e 100755 --- a/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala @@ -104,7 +104,7 @@ trait ActorRefProvider { * Create AskActorRef and register it properly so it can be serialized/deserialized; * caller needs to send the message. */ - def ask(result: Promise[Any], within: Timeout): Option[ActorRef] + def ask(within: Timeout): Option[PromiseActorRef] /** * This Future is completed upon termination of this ActorRefProvider, which @@ -494,12 +494,13 @@ class LocalActorRefProvider( } } - def ask(result: Promise[Any], within: Timeout): Option[ActorRef] = { + def ask(within: Timeout): Option[PromiseActorRef] = { (if (within == null) settings.ActorTimeout else within) match { case t if t.duration.length <= 0 ⇒ None case t ⇒ val path = tempPath() val name = path.name + val result = Promise[Any]()(dispatcher) val a = new PromiseActorRef(path, tempContainer, result, deathWatch) tempContainer.addChild(name, a) val f = dispatcher.prerequisites.scheduler.scheduleOnce(t.duration) { result.failure(new AskTimeoutException("Timed out")) } @@ -509,24 +510,6 @@ class LocalActorRefProvider( } Some(a) - - // Alternative implementation: - // Create a full-blown actor to complete the promise. - // This would also work but not as efficient as PromiseActorRef. - //val b = actorOf(system, Props(new Actor { - // def receive = { - // case Status.Success(r) ⇒ result.success(r) - // case Status.Failure(f) ⇒ result.failure(f) - // case other ⇒ result.success(other) - // } - //}), systemGuardian, systemGuardian.path / "promise" / tempName(), false, None) - //val ff = system.scheduler.scheduleOnce(t.duration) { result.failure(new AskTimeoutException("Timed out")) } - //result onComplete { _ ⇒ - // b.stop() - // ff.cancel() - //} - // - //Some(b) } } } diff --git a/akka-actor/src/main/scala/akka/actor/package.scala b/akka-actor/src/main/scala/akka/actor/package.scala index acfbb19e5d..cfe5bc1b0d 100644 --- a/akka-actor/src/main/scala/akka/actor/package.scala +++ b/akka-actor/src/main/scala/akka/actor/package.scala @@ -39,126 +39,3 @@ package object actor { } } - -package object patterns { - - import akka.actor.{ ActorRef, InternalActorRef } - import akka.dispatch.Promise - import akka.util.Timeout - - implicit def ask(actorRef: ActorRef): AskableActorRef = new AskableActorRef()(actorRef) - - // Implicit for converting a Promise to an ActorRef. - // Symmetric to the future2actor conversion, which allows - // piping a Future result (read side) to an Actor's mailbox, this - // conversion allows using an Actor to complete a Promise (write side) - // - // Future.ask / actor ? message is now a trivial implementation that can - // also be done in user code (assuming actorRef, timeout and dispatcher implicits): - // - // Patterns.ask(actor, message) = { - // val promise = Promise[Any]() - // actor ! (message, promise) - // promise - // } - - @inline implicit def promise2actorRef(promise: Promise[Any])(implicit actorRef: ActorRef, timeout: Timeout): ActorRef = { - val provider = actorRef.asInstanceOf[InternalActorRef].provider - provider.ask(promise, timeout) match { - case Some(ref) ⇒ ref - case None ⇒ null - } - } - -} - -package patterns { - - import akka.actor.{ ActorRef, InternalActorRef } - import akka.dispatch.{ Future, Promise } - import akka.util.Timeout - - final class AskableActorRef(implicit val actorRef: ActorRef) { - - /** - * Akka Java API. - * - * Sends a message asynchronously returns a future holding the eventual reply message. - * The Future will be completed with an [[akka.actor.AskTimeoutException]] after the given - * timeout has expired. - * - * NOTE: - * Use this method with care. In most cases it is better to use 'tell' together with the sender - * parameter to implement non-blocking request/response message exchanges. - * - * If you are sending messages using ask and using blocking operations on the Future, such as - * 'get', then you have to use getContext().sender().tell(...) - * in the target actor to send a reply message to the original sender, and thereby completing the Future, - * otherwise the sender will block until the timeout expires. - * - * When using future callbacks, inside actors you need to carefully avoid closing over - * the containing actor’s reference, i.e. do not call methods or access mutable state - * on the enclosing actor from within the callback. This would break the actor - * encapsulation and may introduce synchronization bugs and race conditions because - * the callback will be scheduled concurrently to the enclosing actor. Unfortunately - * there is not yet a way to detect these illegal accesses at compile time. - */ - def ask(message: AnyRef, timeout: Timeout): Future[AnyRef] = ?(message, timeout).asInstanceOf[Future[AnyRef]] - - def ask(message: AnyRef, timeoutMillis: Long): Future[AnyRef] = ask(message, new Timeout(timeoutMillis)) - - /** - * Sends a message asynchronously, returning a future which may eventually hold the reply. - * The Future will be completed with an [[akka.actor.AskTimeoutException]] after the given - * timeout has expired. - * - * NOTE: - * Use this method with care. In most cases it is better to use '!' together with implicit or explicit - * sender parameter to implement non-blocking request/response message exchanges. - * - * If you are sending messages using ask and using blocking operations on the Future, such as - * 'get', then you have to use getContext().sender().tell(...) - * in the target actor to send a reply message to the original sender, and thereby completing the Future, - * otherwise the sender will block until the timeout expires. - * - * When using future callbacks, inside actors you need to carefully avoid closing over - * the containing actor’s reference, i.e. do not call methods or access mutable state - * on the enclosing actor from within the callback. This would break the actor - * encapsulation and may introduce synchronization bugs and race conditions because - * the callback will be scheduled concurrently to the enclosing actor. Unfortunately - * there is not yet a way to detect these illegal accesses at compile time. - */ - def ?(message: Any)(implicit timeout: Timeout): Future[Any] = { - implicit val dispatcher = actorRef.asInstanceOf[InternalActorRef].provider.dispatcher - val promise = Promise[Any]() - actorRef.!(message)(promise) - promise - } - - /** - * Sends a message asynchronously, returning a future which may eventually hold the reply. - * The implicit parameter with the default value is just there to disambiguate it from the version that takes the - * implicit timeout - */ - def ?(message: Any, timeout: Timeout)(implicit ignore: Int = 0): Future[Any] = ?(message)(timeout) - } - -} - -object Patterns { - - import akka.actor.ActorRef - import akka.dispatch.Future - import akka.patterns.{ ask ⇒ actorRef2Askable } - import akka.util.Timeout - - def ask(actor: ActorRef, message: Any)(implicit timeout: Timeout): Future[Any] = - actorRef2Askable(actor).?(message) - - def ask(actor: ActorRef, message: Any, timeout: Timeout)(implicit ignore: Int = 0): Future[Any] = - actorRef2Askable(actor).?(message)(timeout) - - def ask(actor: ActorRef, message: Any, timeoutMillis: Long): Future[Any] = - actorRef2Askable(actor).?(message)(new Timeout(timeoutMillis)) - -} diff --git a/akka-actor/src/main/scala/akka/patterns/AskableActorRef.scala b/akka-actor/src/main/scala/akka/patterns/AskableActorRef.scala new file mode 100644 index 0000000000..1b42fc664c --- /dev/null +++ b/akka-actor/src/main/scala/akka/patterns/AskableActorRef.scala @@ -0,0 +1,84 @@ +/** + * Copyright (C) 2009-2011 Typesafe Inc. + */ +package akka.patterns + +import akka.actor.{ ActorRef, InternalActorRef, AskTimeoutException } +import akka.dispatch.{ Future, Promise } +import akka.util.Timeout + +final class AskableActorRef(val actorRef: ActorRef) { + + /** + * Sends a message asynchronously and returns a [[akka.dispatch.Future]] + * holding the eventual reply message; this means that the target actor + * needs to send the result to the `sender` reference provided. The Future + * will be completed with an [[akka.actor.AskTimeoutException]] after the + * given timeout has expired; this is independent from any timeout applied + * while awaiting a result for this future (i.e. in + * `Await.result(..., timeout)`). + * + * Warning: + * When using future callbacks, inside actors you need to carefully avoid closing over + * the containing actor’s object, i.e. do not call methods or access mutable state + * on the enclosing actor from within the callback. This would break the actor + * encapsulation and may introduce synchronization bugs and race conditions because + * the callback will be scheduled concurrently to the enclosing actor. Unfortunately + * there is not yet a way to detect these illegal accesses at compile time. + * + * Recommended usage: + * + * {{{ + * val f = worker.ask(request)(timeout) + * flow { + * EnrichedRequest(request, f()) + * } pipeTo nextActor + * }}} + * + * [see the [[akka.dispatch.Future]] companion object for a description of `flow`] + */ + def ask(message: AnyRef)(implicit timeout: Timeout): Future[Any] = akka.patterns.ask(actorRef, message)(timeout) + + /** + * Sends a message asynchronously and returns a [[akka.dispatch.Future]] + * holding the eventual reply message; this means that the target actor + * needs to send the result to the `sender` reference provided. The Future + * will be completed with an [[akka.actor.AskTimeoutException]] after the + * given timeout has expired; this is independent from any timeout applied + * while awaiting a result for this future (i.e. in + * `Await.result(..., timeout)`). + * + * Warning: + * When using future callbacks, inside actors you need to carefully avoid closing over + * the containing actor’s object, i.e. do not call methods or access mutable state + * on the enclosing actor from within the callback. This would break the actor + * encapsulation and may introduce synchronization bugs and race conditions because + * the callback will be scheduled concurrently to the enclosing actor. Unfortunately + * there is not yet a way to detect these illegal accesses at compile time. + * + * Recommended usage: + * + * {{{ + * val f = worker ? request + * flow { + * EnrichedRequest(request, f()) + * } pipeTo nextActor + * }}} + * + * [see the [[akka.dispatch.Future]] companion object for a description of `flow`] + */ + def ?(message: Any)(implicit timeout: Timeout): Future[Any] = akka.patterns.ask(actorRef, message) + + /* + * FIXME: I think this should be removed, since it introduces an “ambiguity” + * when sending Tuple2, which the compiler resolves unexpectedly to this + * method; also overloading is bad, isn’t it? - RK (ticket #1653) + */ + /** + * Sends a message asynchronously, returning a future which may eventually hold the reply. + * The implicit parameter with the default value is just there to disambiguate it from the version that takes the + * implicit timeout + */ + def ?(message: Any, timeout: Timeout)(implicit ignore: Int = 0): Future[Any] = ?(message)(timeout) + +} diff --git a/akka-actor/src/main/scala/akka/patterns/package.scala b/akka-actor/src/main/scala/akka/patterns/package.scala new file mode 100644 index 0000000000..d0cd07766a --- /dev/null +++ b/akka-actor/src/main/scala/akka/patterns/package.scala @@ -0,0 +1,70 @@ +/** + * Copyright (C) 2009-2011 Typesafe Inc. + */ +package akka + +package object patterns { + + import akka.actor.{ ActorRef, InternalActorRef, ActorRefWithProvider, AskTimeoutException } + import akka.dispatch.{ Future, Promise } + import akka.util.Timeout + + /** + * Import this implicit conversion to gain `?` and `ask` methods on + * [[akka.actor.ActorRef]], which will defer to the + * `ask(actorRef, message)(timeout)` method defined here. + * + * {{{ + * import akka.patterns.ask + * + * val future = actor ? message // => ask(actor, message) + * val future = actor ask message // => ask(actor, message) + * val future = actor.ask(message)(timeout) // => ask(actor, message)(timeout) + * }}} + * + * All of the above use an implicit [[akka.actor.Timeout]]. + */ + implicit def ask(actorRef: ActorRef): AskableActorRef = new AskableActorRef(actorRef) + + /** + * Sends a message asynchronously and returns a [[akka.dispatch.Future]] + * holding the eventual reply message; this means that the target actor + * needs to send the result to the `sender` reference provided. The Future + * will be completed with an [[akka.actor.AskTimeoutException]] after the + * given timeout has expired; this is independent from any timeout applied + * while awaiting a result for this future (i.e. in + * `Await.result(..., timeout)`). + * + * Warning: + * When using future callbacks, inside actors you need to carefully avoid closing over + * the containing actor’s object, i.e. do not call methods or access mutable state + * on the enclosing actor from within the callback. This would break the actor + * encapsulation and may introduce synchronization bugs and race conditions because + * the callback will be scheduled concurrently to the enclosing actor. Unfortunately + * there is not yet a way to detect these illegal accesses at compile time. + * + * Recommended usage: + * + * {{{ + * val f = ask(worker, request)(timeout) + * flow { + * EnrichedRequest(request, f()) + * } pipeTo nextActor + * }}} + * + * [see [[akka.dispatch.Future]] for a description of `flow`] + */ + def ask(actorRef: ActorRef, message: Any)(implicit timeout: Timeout): Future[Any] = actorRef match { + case ref: ActorRefWithProvider ⇒ + ref.provider.ask(timeout) match { + case Some(ref) ⇒ + actorRef.tell(message, ref) + ref.result + case None ⇒ + actorRef.tell(message) + Promise.failed(new AskTimeoutException("failed to create PromiseActorRef"))(ref.provider.dispatcher) + } + case _ ⇒ throw new IllegalArgumentException("incompatible ActorRef " + actorRef) + } + +} diff --git a/akka-actor/src/main/scala/akka/routing/Routing.scala b/akka-actor/src/main/scala/akka/routing/Routing.scala index 36f5fe9670..11f8fee4af 100644 --- a/akka-actor/src/main/scala/akka/routing/Routing.scala +++ b/akka-actor/src/main/scala/akka/routing/Routing.scala @@ -351,10 +351,7 @@ trait BroadcastLike { this: RouterConfig ⇒ createAndRegisterRoutees(props, context, nrOfInstances, routees) { - case (sender, message) ⇒ - message match { - case _ ⇒ toAll(sender, ref.routees) - } + case (sender, message) ⇒ toAll(sender, ref.routees) } } } @@ -407,12 +404,9 @@ trait ScatterGatherFirstCompletedLike { this: RouterConfig ⇒ { case (sender, message) ⇒ val provider: ActorRefProvider = context.asInstanceOf[ActorCell].systemImpl.provider - val promise = Promise[Any]()(provider.dispatcher) - val asker = provider.ask(promise, Timeout(within)).get - promise.pipeTo(sender) - message match { - case _ ⇒ toAll(asker, ref.routees) - } + val asker = provider.ask(Timeout(within)).get + asker.result.pipeTo(sender) + toAll(asker, ref.routees) } } } diff --git a/akka-docs/scala/code/akka/docs/actor/ActorDocSpec.scala b/akka-docs/scala/code/akka/docs/actor/ActorDocSpec.scala index f804e29bac..fac3411cde 100644 --- a/akka-docs/scala/code/akka/docs/actor/ActorDocSpec.scala +++ b/akka-docs/scala/code/akka/docs/actor/ActorDocSpec.scala @@ -8,7 +8,6 @@ import akka.actor.Actor import akka.actor.Props import akka.event.Logging import akka.dispatch.Future -import akka.Patterns //#imports1 @@ -221,6 +220,8 @@ class ActorDocSpec extends AkkaSpec(Map("akka.loglevel" -> "INFO")) { "using ask" in { //#using-ask + import akka.patterns.ask + class MyActor extends Actor { def receive = { case x: String ⇒ sender ! x.toUpperCase @@ -230,10 +231,10 @@ class ActorDocSpec extends AkkaSpec(Map("akka.loglevel" -> "INFO")) { val myActor = system.actorOf(Props(new MyActor), name = "myactor") implicit val timeout = system.settings.ActorTimeout - val future = Patterns.ask(myActor, "hello") + val future = ask(myActor, "hello") for (x ← future) println(x) //Prints "hello" - val result: Future[Int] = for (x ← Patterns.ask(myActor, 3).mapTo[Int]) yield { 2 * x } + val result: Future[Int] = for (x ← ask(myActor, 3).mapTo[Int]) yield { 2 * x } //#using-ask system.stop(myActor) diff --git a/akka-docs/scala/code/akka/docs/future/FutureDocSpec.scala b/akka-docs/scala/code/akka/docs/future/FutureDocSpec.scala index f65f8224db..5c86a0c295 100644 --- a/akka-docs/scala/code/akka/docs/future/FutureDocSpec.scala +++ b/akka-docs/scala/code/akka/docs/future/FutureDocSpec.scala @@ -13,7 +13,6 @@ import akka.dispatch.Future import akka.dispatch.Await import akka.util.duration._ import akka.dispatch.Promise -import akka.Patterns object FutureDocSpec { @@ -45,9 +44,10 @@ class FutureDocSpec extends AkkaSpec { val msg = "hello" //#ask-blocking import akka.dispatch.Await + import akka.patterns.ask implicit val timeout = system.settings.ActorTimeout - val future = Patterns.ask(actor, msg) + val future = actor ? msg // enabled by the “ask” import val result = Await.result(future, timeout.duration).asInstanceOf[String] //#ask-blocking result must be("HELLO") @@ -59,8 +59,9 @@ class FutureDocSpec extends AkkaSpec { implicit val timeout = system.settings.ActorTimeout //#map-to import akka.dispatch.Future + import akka.patterns.ask - val future: Future[String] = Patterns.ask(actor, msg).mapTo[String] + val future: Future[String] = ask(actor, msg).mapTo[String] //#map-to Await.result(future, timeout.duration) must be("HELLO") } @@ -148,15 +149,16 @@ class FutureDocSpec extends AkkaSpec { val msg2 = 2 implicit val timeout = system.settings.ActorTimeout import akka.dispatch.Await + import akka.patterns.ask //#composing-wrong - val f1 = Patterns.ask(actor1, msg1) - val f2 = Patterns.ask(actor2, msg2) + val f1 = ask(actor1, msg1) + val f2 = ask(actor2, msg2) val a = Await.result(f1, 1 second).asInstanceOf[Int] val b = Await.result(f2, 1 second).asInstanceOf[Int] - val f3 = Patterns.ask(actor3, (a + b)) + val f3 = ask(actor3, (a + b)) val result = Await.result(f3, 1 second).asInstanceOf[Int] //#composing-wrong @@ -171,15 +173,16 @@ class FutureDocSpec extends AkkaSpec { val msg2 = 2 implicit val timeout = system.settings.ActorTimeout import akka.dispatch.Await + import akka.patterns.ask //#composing - val f1 = Patterns.ask(actor1, msg1) - val f2 = Patterns.ask(actor2, msg2) + val f1 = ask(actor1, msg1) + val f2 = ask(actor2, msg2) val f3 = for { a ← f1.mapTo[Int] b ← f2.mapTo[Int] - c ← Patterns.ask(actor3, (a + b)).mapTo[Int] + c ← ask(actor3, (a + b)).mapTo[Int] } yield c val result = Await.result(f3, 1 second).asInstanceOf[Int] @@ -192,7 +195,7 @@ class FutureDocSpec extends AkkaSpec { val oddActor = system.actorOf(Props[OddActor]) //#sequence-ask // oddActor returns odd numbers sequentially from 1 as a List[Future[Int]] - val listOfFutures = List.fill(100)(Patterns.ask(oddActor, GetNext).mapTo[Int]) + val listOfFutures = List.fill(100)(akka.patterns.ask(oddActor, GetNext).mapTo[Int]) // now we have a Future[List[Int]] val futureList = Future.sequence(listOfFutures) @@ -240,7 +243,7 @@ class FutureDocSpec extends AkkaSpec { val actor = system.actorOf(Props[MyActor]) val msg1 = -1 //#recover - val future = Patterns.ask(actor, msg1) recover { + val future = akka.patterns.ask(actor, msg1) recover { case e: ArithmeticException ⇒ 0 } //#recover diff --git a/akka-remote/src/main/scala/akka/remote/RemoteActorRefProvider.scala b/akka-remote/src/main/scala/akka/remote/RemoteActorRefProvider.scala index 5b38996d3b..65417d9063 100644 --- a/akka-remote/src/main/scala/akka/remote/RemoteActorRefProvider.scala +++ b/akka-remote/src/main/scala/akka/remote/RemoteActorRefProvider.scala @@ -138,7 +138,7 @@ class RemoteActorRefProvider( def actorFor(ref: InternalActorRef, path: Iterable[String]): InternalActorRef = local.actorFor(ref, path) - def ask(result: Promise[Any], within: Timeout): Option[ActorRef] = local.ask(result, within) + def ask(within: Timeout): Option[PromiseActorRef] = local.ask(within) /** * Using (checking out) actor on a specific node. @@ -160,12 +160,12 @@ trait RemoteRef extends ActorRefScope { * This reference is network-aware (remembers its origin) and immutable. */ private[akka] class RemoteActorRef private[akka] ( - override val provider: RemoteActorRefProvider, + val provider: RemoteActorRefProvider, remote: RemoteSupport[ParsedTransportAddress], val path: ActorPath, val getParent: InternalActorRef, loader: Option[ClassLoader]) - extends InternalActorRef with RemoteRef { + extends InternalActorRef with RemoteRef with ActorRefWithProvider { def getChild(name: Iterator[String]): InternalActorRef = { val s = name.toStream From 2bed2cb9547c235e44cccbc69f82411004b8451c Mon Sep 17 00:00:00 2001 From: Roland Date: Wed, 18 Jan 2012 10:18:51 +0100 Subject: [PATCH 08/18] move everything into package akka.pattern --- .../akka/actor/ActorFireForgetRequestReplySpec.scala | 2 +- .../test/scala/akka/actor/ActorLifeCycleSpec.scala | 2 +- .../src/test/scala/akka/actor/ActorLookupSpec.scala | 2 +- .../src/test/scala/akka/actor/ActorRefSpec.scala | 2 +- .../src/test/scala/akka/actor/ActorTimeoutSpec.scala | 2 +- .../src/test/scala/akka/actor/DeathWatchSpec.scala | 2 +- .../src/test/scala/akka/actor/ForwardActorSpec.scala | 2 +- .../src/test/scala/akka/actor/IOActor.scala | 2 +- .../test/scala/akka/actor/RestartStrategySpec.scala | 2 +- .../src/test/scala/akka/actor/SchedulerSpec.scala | 2 +- .../scala/akka/actor/SupervisorHierarchySpec.scala | 2 +- .../test/scala/akka/actor/SupervisorMiscSpec.scala | 2 +- .../src/test/scala/akka/actor/SupervisorSpec.scala | 2 +- .../test/scala/akka/actor/SupervisorTreeSpec.scala | 2 +- .../src/test/scala/akka/actor/Ticket669Spec.scala | 2 +- .../src/test/scala/akka/actor/TypedActorSpec.scala | 2 +- .../scala/akka/actor/dispatch/ActorModelSpec.scala | 2 +- .../akka/actor/dispatch/DispatcherActorSpec.scala | 2 +- .../scala/akka/actor/dispatch/PinnedActorSpec.scala | 2 +- .../src/test/scala/akka/dataflow/Future2Actor.scala | 2 +- .../src/test/scala/akka/dispatch/FutureSpec.scala | 2 +- .../scala/akka/dispatch/PriorityDispatcherSpec.scala | 2 +- .../src/test/scala/akka/routing/ActorPoolSpec.scala | 2 +- .../akka/routing/ConfiguredLocalRoutingSpec.scala | 2 +- .../src/test/scala/akka/routing/RoutingSpec.scala | 2 +- .../scala/akka/serialization/SerializeSpec.scala | 2 +- .../src/test/scala/akka/ticket/Ticket703Spec.scala | 2 +- akka-actor/src/main/scala/akka/actor/ActorRef.scala | 4 ++-- .../src/main/scala/akka/actor/ActorSystem.scala | 2 +- .../src/main/scala/akka/actor/TypedActor.scala | 2 +- akka-actor/src/main/scala/akka/event/Logging.scala | 2 +- .../akka/{patterns => pattern}/AskableActorRef.scala | 6 +++--- .../src/main/scala/akka/{ => pattern}/Patterns.scala | 6 +++--- .../scala/akka/{patterns => pattern}/package.scala | 4 ++-- akka-agent/src/main/scala/akka/agent/Agent.scala | 2 +- .../code/akka/docs/actor/FaultHandlingTestBase.java | 2 +- .../akka/docs/actor/UntypedActorDocTestBase.java | 2 +- .../code/akka/docs/future/FutureDocTestBase.java | 2 +- .../code/akka/docs/transactor/TransactorDocTest.java | 2 +- .../scala/code/akka/docs/actor/ActorDocSpec.scala | 6 +++--- .../scala/code/akka/docs/future/FutureDocSpec.scala | 12 ++++++------ .../code/akka/docs/routing/RouterTypeExample.scala | 2 +- .../code/akka/docs/testkit/TestkitDocSpec.scala | 4 ++-- .../akka/docs/transactor/TransactorDocSpec.scala | 2 +- .../src/main/scala/akka/remote/Gossiper.scala | 2 +- .../remote/DirectRoutedRemoteActorMultiJvmSpec.scala | 2 +- .../akka/remote/NewRemoteActorMultiJvmSpec.scala | 2 +- .../remote/RandomRoutedRemoteActorMultiJvmSpec.scala | 2 +- .../RoundRobinRoutedRemoteActorMultiJvmSpec.scala | 2 +- .../scala/akka/remote/RemoteCommunicationSpec.scala | 2 +- .../src/main/scala/akka/testkit/TestActorRef.scala | 2 +- .../src/test/scala/akka/testkit/AkkaSpec.scala | 2 +- .../test/scala/akka/testkit/TestActorRefSpec.scala | 2 +- .../src/test/scala/akka/testkit/TestProbeSpec.scala | 2 +- .../transactor/UntypedCoordinatedIncrementTest.java | 2 +- .../java/akka/transactor/UntypedTransactorTest.java | 2 +- .../akka/transactor/CoordinatedIncrementSpec.scala | 2 +- .../scala/akka/transactor/FickleFriendsSpec.scala | 2 +- .../test/scala/akka/transactor/TransactorSpec.scala | 2 +- 59 files changed, 73 insertions(+), 73 deletions(-) rename akka-actor/src/main/scala/akka/{patterns => pattern}/AskableActorRef.scala (96%) rename akka-actor/src/main/scala/akka/{ => pattern}/Patterns.scala (97%) rename akka-actor/src/main/scala/akka/{patterns => pattern}/package.scala (97%) diff --git a/akka-actor-tests/src/test/scala/akka/actor/ActorFireForgetRequestReplySpec.scala b/akka-actor-tests/src/test/scala/akka/actor/ActorFireForgetRequestReplySpec.scala index 8a4d643e29..4665c8dbf6 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/ActorFireForgetRequestReplySpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/ActorFireForgetRequestReplySpec.scala @@ -8,7 +8,7 @@ import akka.testkit._ import org.scalatest.BeforeAndAfterEach import akka.util.duration._ import akka.dispatch.Await -import akka.patterns.ask +import akka.pattern.ask object ActorFireForgetRequestReplySpec { diff --git a/akka-actor-tests/src/test/scala/akka/actor/ActorLifeCycleSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/ActorLifeCycleSpec.scala index 016b738c45..e85dffa45b 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/ActorLifeCycleSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/ActorLifeCycleSpec.scala @@ -12,7 +12,7 @@ import akka.testkit._ import akka.util.duration._ import java.util.concurrent.atomic._ import akka.dispatch.Await -import akka.patterns.ask +import akka.pattern.ask object ActorLifeCycleSpec { diff --git a/akka-actor-tests/src/test/scala/akka/actor/ActorLookupSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/ActorLookupSpec.scala index 8a990e18ca..135a7efe0a 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/ActorLookupSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/ActorLookupSpec.scala @@ -6,7 +6,7 @@ package akka.actor import akka.testkit._ import akka.util.duration._ import akka.dispatch.Await -import akka.patterns.ask +import akka.pattern.ask object ActorLookupSpec { diff --git a/akka-actor-tests/src/test/scala/akka/actor/ActorRefSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/ActorRefSpec.scala index a78a99a79b..8dbd1c9a8c 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/ActorRefSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/ActorRefSpec.scala @@ -15,7 +15,7 @@ import akka.util.ReflectiveAccess import akka.serialization.Serialization import java.util.concurrent.{ CountDownLatch, TimeUnit } import akka.dispatch.{ Await, DefaultPromise, Promise, Future } -import akka.patterns.ask +import akka.pattern.ask object ActorRefSpec { diff --git a/akka-actor-tests/src/test/scala/akka/actor/ActorTimeoutSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/ActorTimeoutSpec.scala index 1c9a7e67d6..e5b2303140 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/ActorTimeoutSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/ActorTimeoutSpec.scala @@ -10,7 +10,7 @@ import akka.testkit.DefaultTimeout import java.util.concurrent.TimeoutException import akka.dispatch.Await import akka.util.Timeout -import akka.patterns.ask +import akka.pattern.ask @org.junit.runner.RunWith(classOf[org.scalatest.junit.JUnitRunner]) class ActorTimeoutSpec extends AkkaSpec with BeforeAndAfterAll with DefaultTimeout { diff --git a/akka-actor-tests/src/test/scala/akka/actor/DeathWatchSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/DeathWatchSpec.scala index 1a9c84ecd9..b704991203 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/DeathWatchSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/DeathWatchSpec.scala @@ -8,7 +8,7 @@ import akka.testkit._ import akka.util.duration._ import java.util.concurrent.atomic._ import akka.dispatch.Await -import akka.patterns.ask +import akka.pattern.ask @org.junit.runner.RunWith(classOf[org.scalatest.junit.JUnitRunner]) class LocalDeathWatchSpec extends AkkaSpec with ImplicitSender with DefaultTimeout with DeathWatchSpec diff --git a/akka-actor-tests/src/test/scala/akka/actor/ForwardActorSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/ForwardActorSpec.scala index a019b4afb3..95ecfe1280 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/ForwardActorSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/ForwardActorSpec.scala @@ -9,7 +9,7 @@ import akka.util.duration._ import Actor._ import akka.util.Duration import akka.dispatch.Await -import akka.patterns.ask +import akka.pattern.ask object ForwardActorSpec { val ExpectedMessage = "FOO" diff --git a/akka-actor-tests/src/test/scala/akka/actor/IOActor.scala b/akka-actor-tests/src/test/scala/akka/actor/IOActor.scala index aaa86e9c3e..0d70da3649 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/IOActor.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/IOActor.scala @@ -11,7 +11,7 @@ import akka.util.cps._ import scala.util.continuations._ import akka.testkit._ import akka.dispatch.{ Await, Future } -import akka.patterns.ask +import akka.pattern.ask object IOActorSpec { import IO._ diff --git a/akka-actor-tests/src/test/scala/akka/actor/RestartStrategySpec.scala b/akka-actor-tests/src/test/scala/akka/actor/RestartStrategySpec.scala index 0730b8de7c..49d0359e16 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/RestartStrategySpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/RestartStrategySpec.scala @@ -14,7 +14,7 @@ import akka.testkit.AkkaSpec import akka.testkit.DefaultTimeout import akka.testkit.TestLatch import akka.util.duration._ -import akka.patterns.ask +import akka.pattern.ask @org.junit.runner.RunWith(classOf[org.scalatest.junit.JUnitRunner]) class RestartStrategySpec extends AkkaSpec with DefaultTimeout { diff --git a/akka-actor-tests/src/test/scala/akka/actor/SchedulerSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/SchedulerSpec.scala index 1269558cf9..6d0bde2299 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/SchedulerSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/SchedulerSpec.scala @@ -8,7 +8,7 @@ import java.util.concurrent.{ CountDownLatch, ConcurrentLinkedQueue, TimeUnit } import akka.testkit.DefaultTimeout import akka.testkit.TestLatch import akka.dispatch.Await -import akka.patterns.ask +import akka.pattern.ask @org.junit.runner.RunWith(classOf[org.scalatest.junit.JUnitRunner]) class SchedulerSpec extends AkkaSpec with BeforeAndAfterEach with DefaultTimeout { diff --git a/akka-actor-tests/src/test/scala/akka/actor/SupervisorHierarchySpec.scala b/akka-actor-tests/src/test/scala/akka/actor/SupervisorHierarchySpec.scala index 88139f97f8..883f771547 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/SupervisorHierarchySpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/SupervisorHierarchySpec.scala @@ -8,7 +8,7 @@ import akka.testkit._ import java.util.concurrent.{ TimeUnit, CountDownLatch } import akka.dispatch.Await -import akka.patterns.ask +import akka.pattern.ask object SupervisorHierarchySpec { class FireWorkerException(msg: String) extends Exception(msg) diff --git a/akka-actor-tests/src/test/scala/akka/actor/SupervisorMiscSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/SupervisorMiscSpec.scala index 8b32f76e49..319521fa1f 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/SupervisorMiscSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/SupervisorMiscSpec.scala @@ -8,7 +8,7 @@ import akka.dispatch.{ PinnedDispatcher, Dispatchers, Await } import java.util.concurrent.{ TimeUnit, CountDownLatch } import akka.testkit.AkkaSpec import akka.testkit.DefaultTimeout -import akka.patterns.ask +import akka.pattern.ask object SupervisorMiscSpec { val config = """ diff --git a/akka-actor-tests/src/test/scala/akka/actor/SupervisorSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/SupervisorSpec.scala index 8405e29e8e..90b3b2d760 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/SupervisorSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/SupervisorSpec.scala @@ -11,7 +11,7 @@ import akka.testkit.TestEvent._ import akka.testkit._ import java.util.concurrent.atomic.AtomicInteger import akka.dispatch.Await -import akka.patterns.ask +import akka.pattern.ask object SupervisorSpec { val Timeout = 5 seconds diff --git a/akka-actor-tests/src/test/scala/akka/actor/SupervisorTreeSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/SupervisorTreeSpec.scala index 6ebca690a7..8c8284ec2a 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/SupervisorTreeSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/SupervisorTreeSpec.scala @@ -12,7 +12,7 @@ import akka.testkit.AkkaSpec import akka.testkit.ImplicitSender import akka.testkit.DefaultTimeout import akka.dispatch.{ Await, Dispatchers } -import akka.patterns.ask +import akka.pattern.ask @org.junit.runner.RunWith(classOf[org.scalatest.junit.JUnitRunner]) class SupervisorTreeSpec extends AkkaSpec with ImplicitSender with DefaultTimeout { diff --git a/akka-actor-tests/src/test/scala/akka/actor/Ticket669Spec.scala b/akka-actor-tests/src/test/scala/akka/actor/Ticket669Spec.scala index f3a0784da2..54aa978ba9 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/Ticket669Spec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/Ticket669Spec.scala @@ -11,7 +11,7 @@ import akka.testkit.AkkaSpec import akka.testkit.ImplicitSender import akka.testkit.DefaultTimeout import akka.dispatch.Await -import akka.patterns.ask +import akka.pattern.ask @org.junit.runner.RunWith(classOf[org.scalatest.junit.JUnitRunner]) class Ticket669Spec extends AkkaSpec with BeforeAndAfterAll with ImplicitSender with DefaultTimeout { diff --git a/akka-actor-tests/src/test/scala/akka/actor/TypedActorSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/TypedActorSpec.scala index 7cde57720c..28e8fb8d8f 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/TypedActorSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/TypedActorSpec.scala @@ -18,7 +18,7 @@ import java.util.concurrent.{ TimeUnit, CountDownLatch } import akka.japi.{ Creator, Option ⇒ JOption } import akka.testkit.DefaultTimeout import akka.dispatch.{ Await, Dispatchers, Future, Promise } -import akka.patterns.ask +import akka.pattern.ask object TypedActorSpec { diff --git a/akka-actor-tests/src/test/scala/akka/actor/dispatch/ActorModelSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/dispatch/ActorModelSpec.scala index c242617753..c9cddba4b3 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/dispatch/ActorModelSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/dispatch/ActorModelSpec.scala @@ -20,7 +20,7 @@ import akka.util.duration._ import akka.event.Logging.Error import com.typesafe.config.Config import akka.util.Duration -import akka.patterns.ask +import akka.pattern.ask object ActorModelSpec { diff --git a/akka-actor-tests/src/test/scala/akka/actor/dispatch/DispatcherActorSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/dispatch/DispatcherActorSpec.scala index 1160883e09..2dce8346db 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/dispatch/DispatcherActorSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/dispatch/DispatcherActorSpec.scala @@ -8,7 +8,7 @@ import akka.util.Duration import akka.util.duration._ import akka.testkit.DefaultTimeout import akka.dispatch.{ Await, PinnedDispatcher, Dispatchers, Dispatcher } -import akka.patterns.ask +import akka.pattern.ask object DispatcherActorSpec { val config = """ diff --git a/akka-actor-tests/src/test/scala/akka/actor/dispatch/PinnedActorSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/dispatch/PinnedActorSpec.scala index 4ddcb8ba12..6c66784e5d 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/dispatch/PinnedActorSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/dispatch/PinnedActorSpec.scala @@ -7,7 +7,7 @@ import akka.actor.{ Props, Actor } import akka.testkit.AkkaSpec import org.scalatest.BeforeAndAfterEach import akka.dispatch.{ Await, PinnedDispatcher, Dispatchers } -import akka.patterns.ask +import akka.pattern.ask object PinnedActorSpec { val config = """ diff --git a/akka-actor-tests/src/test/scala/akka/dataflow/Future2Actor.scala b/akka-actor-tests/src/test/scala/akka/dataflow/Future2Actor.scala index 48992a5ee7..91cc9b2c93 100644 --- a/akka-actor-tests/src/test/scala/akka/dataflow/Future2Actor.scala +++ b/akka-actor-tests/src/test/scala/akka/dataflow/Future2Actor.scala @@ -9,7 +9,7 @@ import akka.actor.future2actor import akka.util.duration._ import akka.testkit.AkkaSpec import akka.testkit.DefaultTimeout -import akka.patterns.ask +import akka.pattern.ask class Future2ActorSpec extends AkkaSpec with DefaultTimeout { diff --git a/akka-actor-tests/src/test/scala/akka/dispatch/FutureSpec.scala b/akka-actor-tests/src/test/scala/akka/dispatch/FutureSpec.scala index c874ea68b7..face8580f2 100644 --- a/akka-actor-tests/src/test/scala/akka/dispatch/FutureSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/dispatch/FutureSpec.scala @@ -16,7 +16,7 @@ import akka.testkit.DefaultTimeout import akka.testkit.TestLatch import java.util.concurrent.{ TimeoutException, TimeUnit, CountDownLatch } import scala.runtime.NonLocalReturnControl -import akka.patterns.ask +import akka.pattern.ask object FutureSpec { class TestActor extends Actor { diff --git a/akka-actor-tests/src/test/scala/akka/dispatch/PriorityDispatcherSpec.scala b/akka-actor-tests/src/test/scala/akka/dispatch/PriorityDispatcherSpec.scala index 82fcc372fa..2bb4ab73e5 100644 --- a/akka-actor-tests/src/test/scala/akka/dispatch/PriorityDispatcherSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/dispatch/PriorityDispatcherSpec.scala @@ -2,7 +2,7 @@ package akka.dispatch import akka.actor.{ Props, LocalActorRef, Actor } import akka.testkit.AkkaSpec -import akka.patterns.ask +import akka.pattern.ask import akka.util.duration._ import akka.testkit.DefaultTimeout import com.typesafe.config.Config diff --git a/akka-actor-tests/src/test/scala/akka/routing/ActorPoolSpec.scala b/akka-actor-tests/src/test/scala/akka/routing/ActorPoolSpec.scala index bfdb168156..5d6cc16eda 100644 --- a/akka-actor-tests/src/test/scala/akka/routing/ActorPoolSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/routing/ActorPoolSpec.scala @@ -6,7 +6,7 @@ import akka.util.duration._ import java.util.concurrent.atomic.{ AtomicBoolean, AtomicInteger } import akka.testkit.AkkaSpec import akka.dispatch.{ Await, Promise, Future } -import akka.patterns.ask +import akka.pattern.ask object ActorPoolSpec { diff --git a/akka-actor-tests/src/test/scala/akka/routing/ConfiguredLocalRoutingSpec.scala b/akka-actor-tests/src/test/scala/akka/routing/ConfiguredLocalRoutingSpec.scala index 2d4a4be1c2..3cc1d6893f 100644 --- a/akka-actor-tests/src/test/scala/akka/routing/ConfiguredLocalRoutingSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/routing/ConfiguredLocalRoutingSpec.scala @@ -6,7 +6,7 @@ import java.util.concurrent.atomic.AtomicInteger import akka.testkit._ import akka.util.duration._ import akka.dispatch.Await -import akka.patterns.ask +import akka.pattern.ask @org.junit.runner.RunWith(classOf[org.scalatest.junit.JUnitRunner]) class ConfiguredLocalRoutingSpec extends AkkaSpec with DefaultTimeout with ImplicitSender { diff --git a/akka-actor-tests/src/test/scala/akka/routing/RoutingSpec.scala b/akka-actor-tests/src/test/scala/akka/routing/RoutingSpec.scala index dff790f50f..ad5afa4383 100644 --- a/akka-actor-tests/src/test/scala/akka/routing/RoutingSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/routing/RoutingSpec.scala @@ -12,7 +12,7 @@ import akka.dispatch.Await import akka.util.Duration import akka.config.ConfigurationException import com.typesafe.config.ConfigFactory -import akka.patterns.ask +import akka.pattern.ask object RoutingSpec { diff --git a/akka-actor-tests/src/test/scala/akka/serialization/SerializeSpec.scala b/akka-actor-tests/src/test/scala/akka/serialization/SerializeSpec.scala index cfec55413d..02e2a30865 100644 --- a/akka-actor-tests/src/test/scala/akka/serialization/SerializeSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/serialization/SerializeSpec.scala @@ -13,7 +13,7 @@ import akka.util.Timeout import akka.util.duration._ import scala.reflect.BeanInfo import com.google.protobuf.Message -import akka.patterns.ask +import akka.pattern.ask class ProtobufSerializer extends Serializer { val ARRAY_OF_BYTE_ARRAY = Array[Class[_]](classOf[Array[Byte]]) diff --git a/akka-actor-tests/src/test/scala/akka/ticket/Ticket703Spec.scala b/akka-actor-tests/src/test/scala/akka/ticket/Ticket703Spec.scala index 63367ff508..7357de4802 100644 --- a/akka-actor-tests/src/test/scala/akka/ticket/Ticket703Spec.scala +++ b/akka-actor-tests/src/test/scala/akka/ticket/Ticket703Spec.scala @@ -5,7 +5,7 @@ import akka.routing._ import akka.testkit.AkkaSpec import akka.dispatch.Await import akka.util.duration._ -import akka.patterns.ask +import akka.pattern.ask @org.junit.runner.RunWith(classOf[org.scalatest.junit.JUnitRunner]) class Ticket703Spec extends AkkaSpec { diff --git a/akka-actor/src/main/scala/akka/actor/ActorRef.scala b/akka-actor/src/main/scala/akka/actor/ActorRef.scala index e7c03e8ae0..9ebae64e62 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorRef.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorRef.scala @@ -168,7 +168,7 @@ trait LocalRef extends ActorRefScope { } /** - * Trait for matching on ActorRefs which have access to a provider; this is used in akka.patterns.ask. + * Trait for matching on ActorRefs which have access to a provider; this is used in akka.pattern.ask. */ trait ActorRefWithProvider { this: InternalActorRef ⇒ def provider: ActorRefProvider @@ -472,7 +472,7 @@ class AskTimeoutException(message: String, cause: Throwable) extends TimeoutExce } /** - * Akka private optimized representation of the temporary actor spawned to + * Akka private optimized representation of the temporary actor spawned to * receive the reply to an "ask" operation. */ private[akka] final class PromiseActorRef( diff --git a/akka-actor/src/main/scala/akka/actor/ActorSystem.scala b/akka-actor/src/main/scala/akka/actor/ActorSystem.scala index 098099c1d1..68a6eb6dc8 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorSystem.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorSystem.scala @@ -7,7 +7,7 @@ import akka.config.ConfigurationException import akka.actor._ import akka.event._ import akka.dispatch._ -import akka.patterns.ask +import akka.pattern.ask import akka.util.duration._ import akka.util.Timeout import akka.util.Timeout._ diff --git a/akka-actor/src/main/scala/akka/actor/TypedActor.scala b/akka-actor/src/main/scala/akka/actor/TypedActor.scala index 87fbd98f47..cc0972c56e 100644 --- a/akka-actor/src/main/scala/akka/actor/TypedActor.scala +++ b/akka-actor/src/main/scala/akka/actor/TypedActor.scala @@ -396,7 +396,7 @@ object TypedActor extends ExtensionId[TypedActorExtension] with ExtensionIdProvi case "equals" ⇒ (args.length == 1 && (proxy eq args(0)) || actor == extension.getActorRefFor(args(0))).asInstanceOf[AnyRef] //Force boxing of the boolean case "hashCode" ⇒ actor.hashCode.asInstanceOf[AnyRef] case _ ⇒ - import akka.patterns.ask + import akka.pattern.ask MethodCall(method, args) match { case m if m.isOneWay ⇒ actor ! m; null //Null return value case m if m.returnsFuture_? ⇒ actor.?(m, timeout) diff --git a/akka-actor/src/main/scala/akka/event/Logging.scala b/akka-actor/src/main/scala/akka/event/Logging.scala index bb0f881c94..6fcf116f80 100644 --- a/akka-actor/src/main/scala/akka/event/Logging.scala +++ b/akka-actor/src/main/scala/akka/event/Logging.scala @@ -158,7 +158,7 @@ trait LoggingBus extends ActorEventBus { val name = "log" + Extension(system).id() + "-" + simpleName(clazz) val actor = system.systemActorOf(Props(clazz), name) implicit val timeout = Timeout(3 seconds) - import akka.patterns.ask + import akka.pattern.ask val response = try Await.result(actor ? InitializeLogger(this), timeout.duration) catch { case _: TimeoutException ⇒ publish(Warning(simpleName(this), "Logger " + name + " did not respond within " + timeout + " to InitializeLogger(bus)")) diff --git a/akka-actor/src/main/scala/akka/patterns/AskableActorRef.scala b/akka-actor/src/main/scala/akka/pattern/AskableActorRef.scala similarity index 96% rename from akka-actor/src/main/scala/akka/patterns/AskableActorRef.scala rename to akka-actor/src/main/scala/akka/pattern/AskableActorRef.scala index 1b42fc664c..faa4c4d5c0 100644 --- a/akka-actor/src/main/scala/akka/patterns/AskableActorRef.scala +++ b/akka-actor/src/main/scala/akka/pattern/AskableActorRef.scala @@ -1,7 +1,7 @@ /** * Copyright (C) 2009-2011 Typesafe Inc. */ -package akka.patterns +package akka.pattern import akka.actor.{ ActorRef, InternalActorRef, AskTimeoutException } import akka.dispatch.{ Future, Promise } @@ -37,7 +37,7 @@ final class AskableActorRef(val actorRef: ActorRef) { * * [see the [[akka.dispatch.Future]] companion object for a description of `flow`] */ - def ask(message: AnyRef)(implicit timeout: Timeout): Future[Any] = akka.patterns.ask(actorRef, message)(timeout) + def ask(message: AnyRef)(implicit timeout: Timeout): Future[Any] = akka.pattern.ask(actorRef, message)(timeout) /** * Sends a message asynchronously and returns a [[akka.dispatch.Future]] @@ -67,7 +67,7 @@ final class AskableActorRef(val actorRef: ActorRef) { * * [see the [[akka.dispatch.Future]] companion object for a description of `flow`] */ - def ?(message: Any)(implicit timeout: Timeout): Future[Any] = akka.patterns.ask(actorRef, message) + def ?(message: Any)(implicit timeout: Timeout): Future[Any] = akka.pattern.ask(actorRef, message) /* * FIXME: I think this should be removed, since it introduces an “ambiguity” diff --git a/akka-actor/src/main/scala/akka/Patterns.scala b/akka-actor/src/main/scala/akka/pattern/Patterns.scala similarity index 97% rename from akka-actor/src/main/scala/akka/Patterns.scala rename to akka-actor/src/main/scala/akka/pattern/Patterns.scala index 7650c4077f..bc86877f40 100644 --- a/akka-actor/src/main/scala/akka/Patterns.scala +++ b/akka-actor/src/main/scala/akka/pattern/Patterns.scala @@ -1,12 +1,12 @@ /** * Copyright (C) 2009-2011 Typesafe Inc. */ -package akka +package akka.pattern object Patterns { import akka.actor.ActorRef import akka.dispatch.Future - import akka.patterns.{ ask ⇒ scalaAsk } + import akka.pattern.{ ask ⇒ scalaAsk } import akka.util.Timeout /** @@ -68,4 +68,4 @@ object Patterns { * }}} */ def ask(actor: ActorRef, message: Any, timeoutMillis: Long): Future[AnyRef] = scalaAsk(actor, message)(new Timeout(timeoutMillis)).asInstanceOf[Future[AnyRef]] -} \ No newline at end of file +} diff --git a/akka-actor/src/main/scala/akka/patterns/package.scala b/akka-actor/src/main/scala/akka/pattern/package.scala similarity index 97% rename from akka-actor/src/main/scala/akka/patterns/package.scala rename to akka-actor/src/main/scala/akka/pattern/package.scala index d0cd07766a..bfd6384c21 100644 --- a/akka-actor/src/main/scala/akka/patterns/package.scala +++ b/akka-actor/src/main/scala/akka/pattern/package.scala @@ -3,7 +3,7 @@ */ package akka -package object patterns { +package object pattern { import akka.actor.{ ActorRef, InternalActorRef, ActorRefWithProvider, AskTimeoutException } import akka.dispatch.{ Future, Promise } @@ -15,7 +15,7 @@ package object patterns { * `ask(actorRef, message)(timeout)` method defined here. * * {{{ - * import akka.patterns.ask + * import akka.pattern.ask * * val future = actor ? message // => ask(actor, message) * val future = actor ask message // => ask(actor, message) diff --git a/akka-agent/src/main/scala/akka/agent/Agent.scala b/akka-agent/src/main/scala/akka/agent/Agent.scala index 8337c0f64b..cd19a0c781 100644 --- a/akka-agent/src/main/scala/akka/agent/Agent.scala +++ b/akka-agent/src/main/scala/akka/agent/Agent.scala @@ -7,7 +7,7 @@ package akka.agent import akka.actor._ import akka.japi.{ Function ⇒ JFunc, Procedure ⇒ JProc } import akka.dispatch._ -import akka.patterns.ask +import akka.pattern.ask import akka.util.Timeout import scala.concurrent.stm._ diff --git a/akka-docs/java/code/akka/docs/actor/FaultHandlingTestBase.java b/akka-docs/java/code/akka/docs/actor/FaultHandlingTestBase.java index f67347b2af..507b812baa 100644 --- a/akka-docs/java/code/akka/docs/actor/FaultHandlingTestBase.java +++ b/akka-docs/java/code/akka/docs/actor/FaultHandlingTestBase.java @@ -13,7 +13,7 @@ import akka.actor.Props; import akka.actor.Terminated; import akka.actor.UntypedActor; import akka.dispatch.Await; -import static akka.Patterns.ask; +import static akka.pattern.Patterns.ask; import akka.util.Duration; import akka.testkit.AkkaSpec; import akka.testkit.TestProbe; diff --git a/akka-docs/java/code/akka/docs/actor/UntypedActorDocTestBase.java b/akka-docs/java/code/akka/docs/actor/UntypedActorDocTestBase.java index 4944f817f5..fb6aa72d2f 100644 --- a/akka-docs/java/code/akka/docs/actor/UntypedActorDocTestBase.java +++ b/akka-docs/java/code/akka/docs/actor/UntypedActorDocTestBase.java @@ -38,7 +38,7 @@ import org.junit.Test; import scala.Option; import java.lang.Object; import java.util.concurrent.TimeUnit; -import akka.Patterns; +import akka.pattern.Patterns; import static org.junit.Assert.*; diff --git a/akka-docs/java/code/akka/docs/future/FutureDocTestBase.java b/akka-docs/java/code/akka/docs/future/FutureDocTestBase.java index dd10afd165..37f0436b27 100644 --- a/akka-docs/java/code/akka/docs/future/FutureDocTestBase.java +++ b/akka-docs/java/code/akka/docs/future/FutureDocTestBase.java @@ -55,7 +55,7 @@ import akka.actor.UntypedActor; import akka.actor.ActorRef; import akka.actor.Props; import akka.dispatch.Futures; -import akka.Patterns; +import akka.pattern.Patterns; import static org.junit.Assert.*; diff --git a/akka-docs/java/code/akka/docs/transactor/TransactorDocTest.java b/akka-docs/java/code/akka/docs/transactor/TransactorDocTest.java index bb2f069dd0..38b60d4888 100644 --- a/akka-docs/java/code/akka/docs/transactor/TransactorDocTest.java +++ b/akka-docs/java/code/akka/docs/transactor/TransactorDocTest.java @@ -10,7 +10,7 @@ import org.junit.Test; //#imports import akka.actor.*; import akka.dispatch.Await; -import static akka.Patterns.ask; +import static akka.pattern.Patterns.ask; import akka.transactor.Coordinated; import akka.util.Duration; import akka.util.Timeout; diff --git a/akka-docs/scala/code/akka/docs/actor/ActorDocSpec.scala b/akka-docs/scala/code/akka/docs/actor/ActorDocSpec.scala index fac3411cde..7cf551081b 100644 --- a/akka-docs/scala/code/akka/docs/actor/ActorDocSpec.scala +++ b/akka-docs/scala/code/akka/docs/actor/ActorDocSpec.scala @@ -220,7 +220,7 @@ class ActorDocSpec extends AkkaSpec(Map("akka.loglevel" -> "INFO")) { "using ask" in { //#using-ask - import akka.patterns.ask + import akka.pattern.ask class MyActor extends Actor { def receive = { @@ -245,7 +245,7 @@ class ActorDocSpec extends AkkaSpec(Map("akka.loglevel" -> "INFO")) { //#using-implicit-timeout import akka.util.duration._ import akka.util.Timeout - import akka.patterns.ask + import akka.pattern.ask implicit val timeout = Timeout(500 millis) val future = myActor ? "hello" //#using-implicit-timeout @@ -257,7 +257,7 @@ class ActorDocSpec extends AkkaSpec(Map("akka.loglevel" -> "INFO")) { val myActor = system.actorOf(Props(new FirstActor)) //#using-explicit-timeout import akka.util.duration._ - import akka.patterns.ask + import akka.pattern.ask val future = myActor ? ("hello", timeout = 500 millis) //#using-explicit-timeout Await.result(future, 500 millis) must be("hello") diff --git a/akka-docs/scala/code/akka/docs/future/FutureDocSpec.scala b/akka-docs/scala/code/akka/docs/future/FutureDocSpec.scala index 5c86a0c295..cdf866336a 100644 --- a/akka-docs/scala/code/akka/docs/future/FutureDocSpec.scala +++ b/akka-docs/scala/code/akka/docs/future/FutureDocSpec.scala @@ -44,7 +44,7 @@ class FutureDocSpec extends AkkaSpec { val msg = "hello" //#ask-blocking import akka.dispatch.Await - import akka.patterns.ask + import akka.pattern.ask implicit val timeout = system.settings.ActorTimeout val future = actor ? msg // enabled by the “ask” import @@ -59,7 +59,7 @@ class FutureDocSpec extends AkkaSpec { implicit val timeout = system.settings.ActorTimeout //#map-to import akka.dispatch.Future - import akka.patterns.ask + import akka.pattern.ask val future: Future[String] = ask(actor, msg).mapTo[String] //#map-to @@ -149,7 +149,7 @@ class FutureDocSpec extends AkkaSpec { val msg2 = 2 implicit val timeout = system.settings.ActorTimeout import akka.dispatch.Await - import akka.patterns.ask + import akka.pattern.ask //#composing-wrong val f1 = ask(actor1, msg1) @@ -173,7 +173,7 @@ class FutureDocSpec extends AkkaSpec { val msg2 = 2 implicit val timeout = system.settings.ActorTimeout import akka.dispatch.Await - import akka.patterns.ask + import akka.pattern.ask //#composing val f1 = ask(actor1, msg1) @@ -195,7 +195,7 @@ class FutureDocSpec extends AkkaSpec { val oddActor = system.actorOf(Props[OddActor]) //#sequence-ask // oddActor returns odd numbers sequentially from 1 as a List[Future[Int]] - val listOfFutures = List.fill(100)(akka.patterns.ask(oddActor, GetNext).mapTo[Int]) + val listOfFutures = List.fill(100)(akka.pattern.ask(oddActor, GetNext).mapTo[Int]) // now we have a Future[List[Int]] val futureList = Future.sequence(listOfFutures) @@ -243,7 +243,7 @@ class FutureDocSpec extends AkkaSpec { val actor = system.actorOf(Props[MyActor]) val msg1 = -1 //#recover - val future = akka.patterns.ask(actor, msg1) recover { + val future = akka.pattern.ask(actor, msg1) recover { case e: ArithmeticException ⇒ 0 } //#recover diff --git a/akka-docs/scala/code/akka/docs/routing/RouterTypeExample.scala b/akka-docs/scala/code/akka/docs/routing/RouterTypeExample.scala index bc3f370f5b..ebe29a8219 100644 --- a/akka-docs/scala/code/akka/docs/routing/RouterTypeExample.scala +++ b/akka-docs/scala/code/akka/docs/routing/RouterTypeExample.scala @@ -8,7 +8,7 @@ import annotation.tailrec import akka.actor.{ Props, Actor } import akka.util.duration._ import akka.dispatch.Await -import akka.patterns.ask +import akka.pattern.ask case class FibonacciNumber(nbr: Int) diff --git a/akka-docs/scala/code/akka/docs/testkit/TestkitDocSpec.scala b/akka-docs/scala/code/akka/docs/testkit/TestkitDocSpec.scala index b3ff8d2e05..89d95b3252 100644 --- a/akka-docs/scala/code/akka/docs/testkit/TestkitDocSpec.scala +++ b/akka-docs/scala/code/akka/docs/testkit/TestkitDocSpec.scala @@ -120,7 +120,7 @@ class TestkitDocSpec extends AkkaSpec with DefaultTimeout with ImplicitSender { import akka.testkit.TestActorRef import akka.util.duration._ import akka.dispatch.Await - import akka.patterns.ask + import akka.pattern.ask val actorRef = TestActorRef(new MyActor) // hypothetical message stimulating a '42' answer @@ -204,7 +204,7 @@ class TestkitDocSpec extends AkkaSpec with DefaultTimeout with ImplicitSender { "demonstrate probe reply" in { import akka.testkit.TestProbe import akka.util.duration._ - import akka.patterns.ask + import akka.pattern.ask //#test-probe-reply val probe = TestProbe() val future = probe.ref ? "hello" diff --git a/akka-docs/scala/code/akka/docs/transactor/TransactorDocSpec.scala b/akka-docs/scala/code/akka/docs/transactor/TransactorDocSpec.scala index 2cde9c9890..ed94589499 100644 --- a/akka-docs/scala/code/akka/docs/transactor/TransactorDocSpec.scala +++ b/akka-docs/scala/code/akka/docs/transactor/TransactorDocSpec.scala @@ -141,7 +141,7 @@ class TransactorDocSpec extends AkkaSpec { import akka.dispatch.Await import akka.util.duration._ import akka.util.Timeout - import akka.patterns.ask + import akka.pattern.ask val system = ActorSystem("app") diff --git a/akka-remote/src/main/scala/akka/remote/Gossiper.scala b/akka-remote/src/main/scala/akka/remote/Gossiper.scala index 3ff54b5efe..788e86bb1c 100644 --- a/akka-remote/src/main/scala/akka/remote/Gossiper.scala +++ b/akka-remote/src/main/scala/akka/remote/Gossiper.scala @@ -22,7 +22,7 @@ import scala.annotation.tailrec import com.google.protobuf.ByteString import java.util.concurrent.TimeoutException import akka.dispatch.Await -import akka.patterns.ask +import akka.pattern.ask /** * Interface for node membership change listener. diff --git a/akka-remote/src/multi-jvm/scala/akka/remote/DirectRoutedRemoteActorMultiJvmSpec.scala b/akka-remote/src/multi-jvm/scala/akka/remote/DirectRoutedRemoteActorMultiJvmSpec.scala index 58c52d8971..36ba02a980 100644 --- a/akka-remote/src/multi-jvm/scala/akka/remote/DirectRoutedRemoteActorMultiJvmSpec.scala +++ b/akka-remote/src/multi-jvm/scala/akka/remote/DirectRoutedRemoteActorMultiJvmSpec.scala @@ -5,7 +5,7 @@ import akka.routing._ import akka.actor.{ Actor, Props } import akka.testkit._ import akka.dispatch.Await -import akka.patterns.ask +import akka.pattern.ask object DirectRoutedRemoteActorMultiJvmSpec extends AbstractRemoteActorMultiJvmSpec { override def NrOfNodes = 2 diff --git a/akka-remote/src/multi-jvm/scala/akka/remote/NewRemoteActorMultiJvmSpec.scala b/akka-remote/src/multi-jvm/scala/akka/remote/NewRemoteActorMultiJvmSpec.scala index cc8f62552c..cfdb6ae2dd 100644 --- a/akka-remote/src/multi-jvm/scala/akka/remote/NewRemoteActorMultiJvmSpec.scala +++ b/akka-remote/src/multi-jvm/scala/akka/remote/NewRemoteActorMultiJvmSpec.scala @@ -6,7 +6,7 @@ import akka.routing._ import akka.testkit._ import akka.util.duration._ import akka.dispatch.Await -import akka.patterns.ask +import akka.pattern.ask object NewRemoteActorMultiJvmSpec extends AbstractRemoteActorMultiJvmSpec { override def NrOfNodes = 2 diff --git a/akka-remote/src/multi-jvm/scala/akka/remote/RandomRoutedRemoteActorMultiJvmSpec.scala b/akka-remote/src/multi-jvm/scala/akka/remote/RandomRoutedRemoteActorMultiJvmSpec.scala index d466c014b3..2c81d9d03d 100644 --- a/akka-remote/src/multi-jvm/scala/akka/remote/RandomRoutedRemoteActorMultiJvmSpec.scala +++ b/akka-remote/src/multi-jvm/scala/akka/remote/RandomRoutedRemoteActorMultiJvmSpec.scala @@ -5,7 +5,7 @@ import akka.remote._ import akka.routing._ import akka.testkit.DefaultTimeout import akka.dispatch.Await -import akka.patterns.ask +import akka.pattern.ask object RandomRoutedRemoteActorMultiJvmSpec extends AbstractRemoteActorMultiJvmSpec { override def NrOfNodes = 4 diff --git a/akka-remote/src/multi-jvm/scala/akka/remote/RoundRobinRoutedRemoteActorMultiJvmSpec.scala b/akka-remote/src/multi-jvm/scala/akka/remote/RoundRobinRoutedRemoteActorMultiJvmSpec.scala index 22eb8cd8c3..8381e14755 100644 --- a/akka-remote/src/multi-jvm/scala/akka/remote/RoundRobinRoutedRemoteActorMultiJvmSpec.scala +++ b/akka-remote/src/multi-jvm/scala/akka/remote/RoundRobinRoutedRemoteActorMultiJvmSpec.scala @@ -5,7 +5,7 @@ import akka.remote._ import akka.routing._ import akka.testkit.DefaultTimeout import akka.dispatch.Await -import akka.patterns.ask +import akka.pattern.ask object RoundRobinRoutedRemoteActorMultiJvmSpec extends AbstractRemoteActorMultiJvmSpec { override def NrOfNodes = 4 diff --git a/akka-remote/src/test/scala/akka/remote/RemoteCommunicationSpec.scala b/akka-remote/src/test/scala/akka/remote/RemoteCommunicationSpec.scala index 17068cc351..4f1fb545c0 100644 --- a/akka-remote/src/test/scala/akka/remote/RemoteCommunicationSpec.scala +++ b/akka-remote/src/test/scala/akka/remote/RemoteCommunicationSpec.scala @@ -7,7 +7,7 @@ import akka.testkit._ import akka.actor._ import com.typesafe.config._ import akka.dispatch.Await -import akka.patterns.ask +import akka.pattern.ask object RemoteCommunicationSpec { class Echo extends Actor { diff --git a/akka-testkit/src/main/scala/akka/testkit/TestActorRef.scala b/akka-testkit/src/main/scala/akka/testkit/TestActorRef.scala index 01ce145afa..eb9d12b56a 100644 --- a/akka-testkit/src/main/scala/akka/testkit/TestActorRef.scala +++ b/akka-testkit/src/main/scala/akka/testkit/TestActorRef.scala @@ -13,7 +13,7 @@ import java.util.concurrent.atomic.AtomicLong import akka.event.EventStream import scala.collection.immutable.Stack import akka.dispatch._ -import akka.patterns.ask +import akka.pattern.ask /** * This special ActorRef is exclusively for use during unit testing in a single-threaded environment. Therefore, it diff --git a/akka-testkit/src/test/scala/akka/testkit/AkkaSpec.scala b/akka-testkit/src/test/scala/akka/testkit/AkkaSpec.scala index e47587fc9c..329d11fc39 100644 --- a/akka-testkit/src/test/scala/akka/testkit/AkkaSpec.scala +++ b/akka-testkit/src/test/scala/akka/testkit/AkkaSpec.scala @@ -17,7 +17,7 @@ import akka.actor.DeadLetter import java.util.concurrent.TimeoutException import akka.dispatch.{ Await, MessageDispatcher } import akka.dispatch.Dispatchers -import akka.patterns.ask +import akka.pattern.ask object TimingTest extends Tag("timing") diff --git a/akka-testkit/src/test/scala/akka/testkit/TestActorRefSpec.scala b/akka-testkit/src/test/scala/akka/testkit/TestActorRefSpec.scala index b742165f1d..18359fcfda 100644 --- a/akka-testkit/src/test/scala/akka/testkit/TestActorRefSpec.scala +++ b/akka-testkit/src/test/scala/akka/testkit/TestActorRefSpec.scala @@ -10,7 +10,7 @@ import akka.event.Logging.Warning import akka.dispatch.{ Future, Promise, Await } import akka.util.duration._ import akka.actor.ActorSystem -import akka.patterns.ask +import akka.pattern.ask /** * Test whether TestActorRef behaves as an ActorRef should, besides its own spec. diff --git a/akka-testkit/src/test/scala/akka/testkit/TestProbeSpec.scala b/akka-testkit/src/test/scala/akka/testkit/TestProbeSpec.scala index 6a4a9db420..516bba7322 100644 --- a/akka-testkit/src/test/scala/akka/testkit/TestProbeSpec.scala +++ b/akka-testkit/src/test/scala/akka/testkit/TestProbeSpec.scala @@ -6,7 +6,7 @@ import org.scalatest.{ BeforeAndAfterEach, WordSpec } import akka.actor._ import akka.util.duration._ import akka.dispatch.{ Await, Future } -import akka.patterns.ask +import akka.pattern.ask @org.junit.runner.RunWith(classOf[org.scalatest.junit.JUnitRunner]) class TestProbeSpec extends AkkaSpec with DefaultTimeout { diff --git a/akka-transactor/src/test/java/akka/transactor/UntypedCoordinatedIncrementTest.java b/akka-transactor/src/test/java/akka/transactor/UntypedCoordinatedIncrementTest.java index d282a638fc..3ae9046c8b 100644 --- a/akka-transactor/src/test/java/akka/transactor/UntypedCoordinatedIncrementTest.java +++ b/akka-transactor/src/test/java/akka/transactor/UntypedCoordinatedIncrementTest.java @@ -18,7 +18,7 @@ import akka.actor.UntypedActor; import akka.actor.UntypedActorFactory; import akka.dispatch.Await; import akka.dispatch.Future; -import static akka.Patterns.ask; +import static akka.pattern.Patterns.ask; import akka.testkit.AkkaSpec; import akka.testkit.EventFilter; import akka.testkit.ErrorFilter; diff --git a/akka-transactor/src/test/java/akka/transactor/UntypedTransactorTest.java b/akka-transactor/src/test/java/akka/transactor/UntypedTransactorTest.java index 2a6e30ea81..8898ec096f 100644 --- a/akka-transactor/src/test/java/akka/transactor/UntypedTransactorTest.java +++ b/akka-transactor/src/test/java/akka/transactor/UntypedTransactorTest.java @@ -18,7 +18,7 @@ import akka.actor.UntypedActor; import akka.actor.UntypedActorFactory; import akka.dispatch.Await; import akka.dispatch.Future; -import static akka.Patterns.ask; +import static akka.pattern.Patterns.ask; import akka.testkit.AkkaSpec; import akka.testkit.EventFilter; import akka.testkit.ErrorFilter; diff --git a/akka-transactor/src/test/scala/akka/transactor/CoordinatedIncrementSpec.scala b/akka-transactor/src/test/scala/akka/transactor/CoordinatedIncrementSpec.scala index 2c2e4376e9..b5319b2dc2 100644 --- a/akka-transactor/src/test/scala/akka/transactor/CoordinatedIncrementSpec.scala +++ b/akka-transactor/src/test/scala/akka/transactor/CoordinatedIncrementSpec.scala @@ -12,7 +12,7 @@ import akka.util.duration._ import akka.util.Timeout import akka.testkit._ import scala.concurrent.stm._ -import akka.patterns.ask +import akka.pattern.ask object CoordinatedIncrement { case class Increment(friends: Seq[ActorRef]) diff --git a/akka-transactor/src/test/scala/akka/transactor/FickleFriendsSpec.scala b/akka-transactor/src/test/scala/akka/transactor/FickleFriendsSpec.scala index a8e4e1ad0e..7184c7d520 100644 --- a/akka-transactor/src/test/scala/akka/transactor/FickleFriendsSpec.scala +++ b/akka-transactor/src/test/scala/akka/transactor/FickleFriendsSpec.scala @@ -15,7 +15,7 @@ import akka.testkit.TestEvent.Mute import scala.concurrent.stm._ import scala.util.Random.{ nextInt ⇒ random } import java.util.concurrent.CountDownLatch -import akka.patterns.ask +import akka.pattern.ask object FickleFriends { case class FriendlyIncrement(friends: Seq[ActorRef], timeout: Timeout, latch: CountDownLatch) diff --git a/akka-transactor/src/test/scala/akka/transactor/TransactorSpec.scala b/akka-transactor/src/test/scala/akka/transactor/TransactorSpec.scala index 2d5797c97a..bba7c20612 100644 --- a/akka-transactor/src/test/scala/akka/transactor/TransactorSpec.scala +++ b/akka-transactor/src/test/scala/akka/transactor/TransactorSpec.scala @@ -10,7 +10,7 @@ import akka.util.duration._ import akka.util.Timeout import akka.testkit._ import scala.concurrent.stm._ -import akka.patterns.ask +import akka.pattern.ask object TransactorIncrement { case class Increment(friends: Seq[ActorRef], latch: TestLatch) From 00ec3f89dcb51191b23093570ca56324c167dd14 Mon Sep 17 00:00:00 2001 From: Roland Date: Wed, 18 Jan 2012 11:52:35 +0100 Subject: [PATCH 09/18] move ask machinery from ActorRefProvider to pattern.AskSupport - now everything is assembled in one spot - also moved PromiseActorRef and AskTimeoutException from akka.actor - plus a little boy-scouting --- .../scala/akka/actor/ActorTimeoutSpec.scala | 2 +- .../scala/akka/actor/ForwardActorSpec.scala | 2 +- .../src/main/scala/akka/actor/ActorRef.scala | 38 ----- .../scala/akka/actor/ActorRefProvider.scala | 55 ++++--- .../main/scala/akka/pattern/AskSupport.scala | 142 ++++++++++++++++++ .../scala/akka/pattern/AskableActorRef.scala | 84 ----------- .../main/scala/akka/pattern/Patterns.scala | 32 ++++ .../src/main/scala/akka/pattern/package.scala | 20 +-- .../src/main/scala/akka/routing/Routing.scala | 3 +- .../akka/remote/RemoteActorRefProvider.scala | 7 +- .../akka/remote/RemoteCommunicationSpec.scala | 4 +- 11 files changed, 226 insertions(+), 163 deletions(-) create mode 100644 akka-actor/src/main/scala/akka/pattern/AskSupport.scala delete mode 100644 akka-actor/src/main/scala/akka/pattern/AskableActorRef.scala diff --git a/akka-actor-tests/src/test/scala/akka/actor/ActorTimeoutSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/ActorTimeoutSpec.scala index e5b2303140..de1dd88923 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/ActorTimeoutSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/ActorTimeoutSpec.scala @@ -10,7 +10,7 @@ import akka.testkit.DefaultTimeout import java.util.concurrent.TimeoutException import akka.dispatch.Await import akka.util.Timeout -import akka.pattern.ask +import akka.pattern.{ ask, AskTimeoutException } @org.junit.runner.RunWith(classOf[org.scalatest.junit.JUnitRunner]) class ActorTimeoutSpec extends AkkaSpec with BeforeAndAfterAll with DefaultTimeout { diff --git a/akka-actor-tests/src/test/scala/akka/actor/ForwardActorSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/ForwardActorSpec.scala index 95ecfe1280..cc5eb4c3a9 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/ForwardActorSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/ForwardActorSpec.scala @@ -47,7 +47,7 @@ class ForwardActorSpec extends AkkaSpec { "forward actor reference when invoking forward on ask" in { val chain = createForwardingChain(system) - chain.ask(ExpectedMessage)(5000) onSuccess { case ExpectedMessage ⇒ testActor ! ExpectedMessage } + chain.ask(ExpectedMessage)(5 seconds) onSuccess { case ExpectedMessage ⇒ testActor ! ExpectedMessage } expectMsg(5 seconds, ExpectedMessage) } } diff --git a/akka-actor/src/main/scala/akka/actor/ActorRef.scala b/akka-actor/src/main/scala/akka/actor/ActorRef.scala index 9ebae64e62..a053608a1b 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorRef.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorRef.scala @@ -462,41 +462,3 @@ class VirtualPathContainer(val path: ActorPath, override val getParent: Internal } } } - -/** - * This is what is used to complete a Future that is returned from an ask/? call, - * when it times out. - */ -class AskTimeoutException(message: String, cause: Throwable) extends TimeoutException { - def this(message: String) = this(message, null: Throwable) -} - -/** - * Akka private optimized representation of the temporary actor spawned to - * receive the reply to an "ask" operation. - */ -private[akka] final class PromiseActorRef( - val path: ActorPath, - override val getParent: InternalActorRef, - val result: Promise[Any], - val deathWatch: DeathWatch) extends MinimalActorRef { - - final val running = new AtomicBoolean(true) - - override def !(message: Any)(implicit sender: ActorRef = null): Unit = if (running.get) message match { - case Status.Success(r) ⇒ result.success(r) - case Status.Failure(f) ⇒ result.failure(f) - case other ⇒ result.success(other) - } - - override def sendSystemMessage(message: SystemMessage): Unit = message match { - case _: Terminate ⇒ stop() - case _ ⇒ - } - - override def isTerminated = result.isCompleted - - override def stop(): Unit = if (running.getAndSet(false)) { - deathWatch.publish(Terminated(this)) - } -} diff --git a/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala b/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala index 4408f7562e..50478a248f 100755 --- a/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala @@ -70,6 +70,26 @@ trait ActorRefProvider { def scheduler: Scheduler + /** + * Generates and returns a unique actor path below “/temp”. + */ + def tempPath(): ActorPath + + /** + * Returns the actor reference representing the “/temp” path. + */ + def tempContainer: InternalActorRef + + /** + * Registers an actorRef at a path returned by tempPath(); do NOT pass in any other path. + */ + def registerTempActor(actorRef: InternalActorRef, path: ActorPath) + + /** + * Unregister a temporary actor from the “/temp” path (i.e. obtained from tempPath()); do NOT pass in any other path. + */ + def unregisterTempActor(path: ActorPath) + /** * Actor factory with create-only semantics: will create an actor as * described by props with the given supervisor and path (may be different @@ -100,12 +120,6 @@ trait ActorRefProvider { */ def actorFor(ref: InternalActorRef, p: Iterable[String]): InternalActorRef - /** - * Create AskActorRef and register it properly so it can be serialized/deserialized; - * caller needs to send the message. - */ - def ask(within: Timeout): Option[PromiseActorRef] - /** * This Future is completed upon termination of this ActorRefProvider, which * is usually initiated by stopping the guardian via ActorSystem.stop(). @@ -441,6 +455,16 @@ class LocalActorRefProvider( lazy val tempContainer = new VirtualPathContainer(tempNode, rootGuardian, log) + def registerTempActor(actorRef: InternalActorRef, path: ActorPath): Unit = { + assert(path.parent eq tempNode, "cannot registerTempActor() with anything not obtained from tempPath()") + tempContainer.addChild(path.name, actorRef) + } + + def unregisterTempActor(path: ActorPath): Unit = { + assert(path.parent eq tempNode, "cannot unregisterTempActor() with anything not obtained from tempPath()") + tempContainer.removeChild(path.name) + } + val deathWatch = new LocalDeathWatch(1024) //TODO make configrable def init(_system: ActorSystemImpl) { @@ -493,25 +517,6 @@ class LocalActorRefProvider( new RoutedActorRef(system, props.withRouter(router.adaptFromDeploy(depl)), supervisor, path) } } - - def ask(within: Timeout): Option[PromiseActorRef] = { - (if (within == null) settings.ActorTimeout else within) match { - case t if t.duration.length <= 0 ⇒ None - case t ⇒ - val path = tempPath() - val name = path.name - val result = Promise[Any]()(dispatcher) - val a = new PromiseActorRef(path, tempContainer, result, deathWatch) - tempContainer.addChild(name, a) - val f = dispatcher.prerequisites.scheduler.scheduleOnce(t.duration) { result.failure(new AskTimeoutException("Timed out")) } - result onComplete { _ ⇒ - try { a.stop(); f.cancel() } - finally { tempContainer.removeChild(name) } - } - - Some(a) - } - } } class LocalDeathWatch(val mapSize: Int) extends DeathWatch with ActorClassification { diff --git a/akka-actor/src/main/scala/akka/pattern/AskSupport.scala b/akka-actor/src/main/scala/akka/pattern/AskSupport.scala new file mode 100644 index 0000000000..bc79877fc3 --- /dev/null +++ b/akka-actor/src/main/scala/akka/pattern/AskSupport.scala @@ -0,0 +1,142 @@ +/** + * Copyright (C) 2009-2011 Typesafe Inc. + */ +package akka.pattern + +import java.util.concurrent.atomic.AtomicBoolean +import java.util.concurrent.TimeoutException +import akka.actor.{ Terminated, Status, MinimalActorRef, InternalActorRef, ActorRef, ActorPath } +import akka.dispatch.{ Promise, Terminate, SystemMessage, Future } +import akka.event.DeathWatch +import akka.actor.ActorRefProvider +import akka.util.Timeout + +/** + * This is what is used to complete a Future that is returned from an ask/? call, + * when it times out. + */ +class AskTimeoutException(message: String, cause: Throwable) extends TimeoutException { + def this(message: String) = this(message, null: Throwable) +} + +object AskSupport { + + final class AskableActorRef(val actorRef: ActorRef) { + + /** + * Sends a message asynchronously and returns a [[akka.dispatch.Future]] + * holding the eventual reply message; this means that the target actor + * needs to send the result to the `sender` reference provided. The Future + * will be completed with an [[akka.actor.AskTimeoutException]] after the + * given timeout has expired; this is independent from any timeout applied + * while awaiting a result for this future (i.e. in + * `Await.result(..., timeout)`). + * + * Warning: + * When using future callbacks, inside actors you need to carefully avoid closing over + * the containing actor’s object, i.e. do not call methods or access mutable state + * on the enclosing actor from within the callback. This would break the actor + * encapsulation and may introduce synchronization bugs and race conditions because + * the callback will be scheduled concurrently to the enclosing actor. Unfortunately + * there is not yet a way to detect these illegal accesses at compile time. + * + * Recommended usage: + * + * {{{ + * val f = worker.ask(request)(timeout) + * flow { + * EnrichedRequest(request, f()) + * } pipeTo nextActor + * }}} + * + * [see the [[akka.dispatch.Future]] companion object for a description of `flow`] + */ + def ask(message: AnyRef)(implicit timeout: Timeout): Future[Any] = akka.pattern.ask(actorRef, message)(timeout) + + /** + * Sends a message asynchronously and returns a [[akka.dispatch.Future]] + * holding the eventual reply message; this means that the target actor + * needs to send the result to the `sender` reference provided. The Future + * will be completed with an [[akka.actor.AskTimeoutException]] after the + * given timeout has expired; this is independent from any timeout applied + * while awaiting a result for this future (i.e. in + * `Await.result(..., timeout)`). + * + * Warning: + * When using future callbacks, inside actors you need to carefully avoid closing over + * the containing actor’s object, i.e. do not call methods or access mutable state + * on the enclosing actor from within the callback. This would break the actor + * encapsulation and may introduce synchronization bugs and race conditions because + * the callback will be scheduled concurrently to the enclosing actor. Unfortunately + * there is not yet a way to detect these illegal accesses at compile time. + * + * Recommended usage: + * + * {{{ + * val f = worker ? request + * flow { + * EnrichedRequest(request, f()) + * } pipeTo nextActor + * }}} + * + * [see the [[akka.dispatch.Future]] companion object for a description of `flow`] + */ + def ?(message: Any)(implicit timeout: Timeout): Future[Any] = akka.pattern.ask(actorRef, message) + + /* + * FIXME: I think this should be removed, since it introduces an “ambiguity” + * when sending Tuple2, which the compiler resolves unexpectedly to this + * method; also overloading is bad, isn’t it? - RK (ticket #1653) + */ + /** + * Sends a message asynchronously, returning a future which may eventually hold the reply. + * The implicit parameter with the default value is just there to disambiguate it from the version that takes the + * implicit timeout + */ + def ?(message: Any, timeout: Timeout)(implicit ignore: Int = 0): Future[Any] = ?(message)(timeout) + + } + + /** + * Akka private optimized representation of the temporary actor spawned to + * receive the reply to an "ask" operation. + */ + private[akka] final class PromiseActorRef( + val path: ActorPath, + override val getParent: InternalActorRef, + val result: Promise[Any], + val deathWatch: DeathWatch) extends MinimalActorRef { + + final val running = new AtomicBoolean(true) + + override def !(message: Any)(implicit sender: ActorRef = null): Unit = if (running.get) message match { + case Status.Success(r) ⇒ result.success(r) + case Status.Failure(f) ⇒ result.failure(f) + case other ⇒ result.success(other) + } + + override def sendSystemMessage(message: SystemMessage): Unit = message match { + case _: Terminate ⇒ stop() + case _ ⇒ + } + + override def isTerminated = result.isCompleted + + override def stop(): Unit = if (running.getAndSet(false)) { + deathWatch.publish(Terminated(this)) + } + } + + def createAsker(provider: ActorRefProvider, timeout: Timeout): PromiseActorRef = { + val path = provider.tempPath() + val result = Promise[Any]()(provider.dispatcher) + val a = new PromiseActorRef(path, provider.tempContainer, result, provider.deathWatch) + provider.registerTempActor(a, path) + val f = provider.scheduler.scheduleOnce(timeout.duration) { result.failure(new AskTimeoutException("Timed out")) } + result onComplete { _ ⇒ + try { a.stop(); f.cancel() } + finally { provider.unregisterTempActor(path) } + } + a + } +} diff --git a/akka-actor/src/main/scala/akka/pattern/AskableActorRef.scala b/akka-actor/src/main/scala/akka/pattern/AskableActorRef.scala deleted file mode 100644 index faa4c4d5c0..0000000000 --- a/akka-actor/src/main/scala/akka/pattern/AskableActorRef.scala +++ /dev/null @@ -1,84 +0,0 @@ -/** - * Copyright (C) 2009-2011 Typesafe Inc. - */ -package akka.pattern - -import akka.actor.{ ActorRef, InternalActorRef, AskTimeoutException } -import akka.dispatch.{ Future, Promise } -import akka.util.Timeout - -final class AskableActorRef(val actorRef: ActorRef) { - - /** - * Sends a message asynchronously and returns a [[akka.dispatch.Future]] - * holding the eventual reply message; this means that the target actor - * needs to send the result to the `sender` reference provided. The Future - * will be completed with an [[akka.actor.AskTimeoutException]] after the - * given timeout has expired; this is independent from any timeout applied - * while awaiting a result for this future (i.e. in - * `Await.result(..., timeout)`). - * - * Warning: - * When using future callbacks, inside actors you need to carefully avoid closing over - * the containing actor’s object, i.e. do not call methods or access mutable state - * on the enclosing actor from within the callback. This would break the actor - * encapsulation and may introduce synchronization bugs and race conditions because - * the callback will be scheduled concurrently to the enclosing actor. Unfortunately - * there is not yet a way to detect these illegal accesses at compile time. - * - * Recommended usage: - * - * {{{ - * val f = worker.ask(request)(timeout) - * flow { - * EnrichedRequest(request, f()) - * } pipeTo nextActor - * }}} - * - * [see the [[akka.dispatch.Future]] companion object for a description of `flow`] - */ - def ask(message: AnyRef)(implicit timeout: Timeout): Future[Any] = akka.pattern.ask(actorRef, message)(timeout) - - /** - * Sends a message asynchronously and returns a [[akka.dispatch.Future]] - * holding the eventual reply message; this means that the target actor - * needs to send the result to the `sender` reference provided. The Future - * will be completed with an [[akka.actor.AskTimeoutException]] after the - * given timeout has expired; this is independent from any timeout applied - * while awaiting a result for this future (i.e. in - * `Await.result(..., timeout)`). - * - * Warning: - * When using future callbacks, inside actors you need to carefully avoid closing over - * the containing actor’s object, i.e. do not call methods or access mutable state - * on the enclosing actor from within the callback. This would break the actor - * encapsulation and may introduce synchronization bugs and race conditions because - * the callback will be scheduled concurrently to the enclosing actor. Unfortunately - * there is not yet a way to detect these illegal accesses at compile time. - * - * Recommended usage: - * - * {{{ - * val f = worker ? request - * flow { - * EnrichedRequest(request, f()) - * } pipeTo nextActor - * }}} - * - * [see the [[akka.dispatch.Future]] companion object for a description of `flow`] - */ - def ?(message: Any)(implicit timeout: Timeout): Future[Any] = akka.pattern.ask(actorRef, message) - - /* - * FIXME: I think this should be removed, since it introduces an “ambiguity” - * when sending Tuple2, which the compiler resolves unexpectedly to this - * method; also overloading is bad, isn’t it? - RK (ticket #1653) - */ - /** - * Sends a message asynchronously, returning a future which may eventually hold the reply. - * The implicit parameter with the default value is just there to disambiguate it from the version that takes the - * implicit timeout - */ - def ?(message: Any, timeout: Timeout)(implicit ignore: Int = 0): Future[Any] = ?(message)(timeout) - -} diff --git a/akka-actor/src/main/scala/akka/pattern/Patterns.scala b/akka-actor/src/main/scala/akka/pattern/Patterns.scala index bc86877f40..9f65728517 100644 --- a/akka-actor/src/main/scala/akka/pattern/Patterns.scala +++ b/akka-actor/src/main/scala/akka/pattern/Patterns.scala @@ -9,6 +9,38 @@ object Patterns { import akka.pattern.{ ask ⇒ scalaAsk } import akka.util.Timeout + /** + * Sends a message asynchronously and returns a [[akka.dispatch.Future]] + * holding the eventual reply message; this means that the target actor + * needs to send the result to the `sender` reference provided. The Future + * will be completed with an [[akka.actor.AskTimeoutException]] after the + * given timeout has expired; this is independent from any timeout applied + * while awaiting a result for this future (i.e. in + * `Await.result(..., timeout)`). + * + * This variant will use the `akka.actor.timeout` from the configuration. + * + * Warning: + * When using future callbacks, inside actors you need to carefully avoid closing over + * the containing actor’s object, i.e. do not call methods or access mutable state + * on the enclosing actor from within the callback. This would break the actor + * encapsulation and may introduce synchronization bugs and race conditions because + * the callback will be scheduled concurrently to the enclosing actor. Unfortunately + * there is not yet a way to detect these illegal accesses at compile time. + * + * Recommended usage: + * + * {{{ + * final Future f = Patterns.ask(worker, request, timeout); + * f.onSuccess(new Procedure() { + * public void apply(Object o) { + * nextActor.tell(new EnrichedResult(request, o)); + * } + * }); + * }}} + */ + def ask(actor: ActorRef, message: Any): Future[AnyRef] = scalaAsk(actor, message).asInstanceOf[Future[AnyRef]] + /** * Sends a message asynchronously and returns a [[akka.dispatch.Future]] * holding the eventual reply message; this means that the target actor diff --git a/akka-actor/src/main/scala/akka/pattern/package.scala b/akka-actor/src/main/scala/akka/pattern/package.scala index bfd6384c21..5bc426a67d 100644 --- a/akka-actor/src/main/scala/akka/pattern/package.scala +++ b/akka-actor/src/main/scala/akka/pattern/package.scala @@ -5,7 +5,7 @@ package akka package object pattern { - import akka.actor.{ ActorRef, InternalActorRef, ActorRefWithProvider, AskTimeoutException } + import akka.actor.{ ActorRef, InternalActorRef, ActorRefWithProvider } import akka.dispatch.{ Future, Promise } import akka.util.Timeout @@ -24,7 +24,7 @@ package object pattern { * * All of the above use an implicit [[akka.actor.Timeout]]. */ - implicit def ask(actorRef: ActorRef): AskableActorRef = new AskableActorRef(actorRef) + implicit def ask(actorRef: ActorRef): AskSupport.AskableActorRef = new AskSupport.AskableActorRef(actorRef) /** * Sends a message asynchronously and returns a [[akka.dispatch.Future]] @@ -54,15 +54,17 @@ package object pattern { * * [see [[akka.dispatch.Future]] for a description of `flow`] */ - def ask(actorRef: ActorRef, message: Any)(implicit timeout: Timeout): Future[Any] = actorRef match { + def ask(actorRef: ActorRef, message: Any)(implicit timeout: Timeout = null): Future[Any] = actorRef match { case ref: ActorRefWithProvider ⇒ - ref.provider.ask(timeout) match { - case Some(ref) ⇒ - actorRef.tell(message, ref) - ref.result - case None ⇒ + val provider = ref.provider + (if (timeout == null) provider.settings.ActorTimeout else timeout) match { + case t if t.duration.length <= 0 ⇒ actorRef.tell(message) - Promise.failed(new AskTimeoutException("failed to create PromiseActorRef"))(ref.provider.dispatcher) + Promise.failed(new AskTimeoutException("failed to create PromiseActorRef"))(provider.dispatcher) + case t ⇒ + val a = AskSupport.createAsker(provider, t) + actorRef.tell(message, a) + a.result } case _ ⇒ throw new IllegalArgumentException("incompatible ActorRef " + actorRef) } diff --git a/akka-actor/src/main/scala/akka/routing/Routing.scala b/akka-actor/src/main/scala/akka/routing/Routing.scala index 11f8fee4af..c2f7faaae2 100644 --- a/akka-actor/src/main/scala/akka/routing/Routing.scala +++ b/akka-actor/src/main/scala/akka/routing/Routing.scala @@ -9,6 +9,7 @@ import scala.collection.JavaConversions._ import akka.util.{ Duration, Timeout } import akka.config.ConfigurationException import akka.dispatch.Promise +import akka.pattern.AskSupport /** * A RoutedActorRef is an ActorRef that has a set of connected ActorRef and it uses a Router to @@ -404,7 +405,7 @@ trait ScatterGatherFirstCompletedLike { this: RouterConfig ⇒ { case (sender, message) ⇒ val provider: ActorRefProvider = context.asInstanceOf[ActorCell].systemImpl.provider - val asker = provider.ask(Timeout(within)).get + val asker = AskSupport.createAsker(provider, within) asker.result.pipeTo(sender) toAll(asker, ref.routees) } diff --git a/akka-remote/src/main/scala/akka/remote/RemoteActorRefProvider.scala b/akka-remote/src/main/scala/akka/remote/RemoteActorRefProvider.scala index 65417d9063..fe81dc431e 100644 --- a/akka-remote/src/main/scala/akka/remote/RemoteActorRefProvider.scala +++ b/akka-remote/src/main/scala/akka/remote/RemoteActorRefProvider.scala @@ -39,6 +39,11 @@ class RemoteActorRefProvider( def terminationFuture = local.terminationFuture def dispatcher = local.dispatcher + def registerTempActor(actorRef: InternalActorRef, path: ActorPath) = local.registerTempActor(actorRef, path) + def unregisterTempActor(path: ActorPath) = local.unregisterTempActor(path) + def tempPath() = local.tempPath() + def tempContainer = local.tempContainer + val deployer = new RemoteDeployer(settings) val remote = new Remote(settings, remoteSettings) @@ -138,8 +143,6 @@ class RemoteActorRefProvider( def actorFor(ref: InternalActorRef, path: Iterable[String]): InternalActorRef = local.actorFor(ref, path) - def ask(within: Timeout): Option[PromiseActorRef] = local.ask(within) - /** * Using (checking out) actor on a specific node. */ diff --git a/akka-remote/src/test/scala/akka/remote/RemoteCommunicationSpec.scala b/akka-remote/src/test/scala/akka/remote/RemoteCommunicationSpec.scala index 4f1fb545c0..d9d815d018 100644 --- a/akka-remote/src/test/scala/akka/remote/RemoteCommunicationSpec.scala +++ b/akka-remote/src/test/scala/akka/remote/RemoteCommunicationSpec.scala @@ -83,8 +83,8 @@ akka { "support ask" in { Await.result(here ? "ping", timeout.duration) match { - case ("pong", s: PromiseActorRef) ⇒ // good - case m ⇒ fail(m + " was not (pong, AskActorRef)") + case ("pong", s: akka.pattern.AskSupport.PromiseActorRef) ⇒ // good + case m ⇒ fail(m + " was not (pong, AskActorRef)") } } From 4aa0a1ff2b10bbf69de1687ab8ccb8c731a114d4 Mon Sep 17 00:00:00 2001 From: Roland Date: Wed, 18 Jan 2012 13:01:24 +0100 Subject: [PATCH 10/18] add akka.pattern.pipeTo, see #1582 - move code from akka.actor package to akka.pattern - add Java API in akka.pattern.Patterns.pipeTo() --- .../main/scala/akka/pattern/Patterns.scala | 18 ++++++++++ .../scala/akka/pattern/PipeToSupport.scala | 15 ++++++++ .../src/main/scala/akka/pattern/package.scala | 35 +++++++++++++++++++ 3 files changed, 68 insertions(+) create mode 100644 akka-actor/src/main/scala/akka/pattern/PipeToSupport.scala diff --git a/akka-actor/src/main/scala/akka/pattern/Patterns.scala b/akka-actor/src/main/scala/akka/pattern/Patterns.scala index 9f65728517..50e6bb909c 100644 --- a/akka-actor/src/main/scala/akka/pattern/Patterns.scala +++ b/akka-actor/src/main/scala/akka/pattern/Patterns.scala @@ -100,4 +100,22 @@ object Patterns { * }}} */ def ask(actor: ActorRef, message: Any, timeoutMillis: Long): Future[AnyRef] = scalaAsk(actor, message)(new Timeout(timeoutMillis)).asInstanceOf[Future[AnyRef]] + + /** + * Register an onComplete callback on this [[akka.dispatch.Future]] to send + * the result to the given actor reference. Returns the original Future to + * allow method chaining. + * + * Recommended usage example: + * + * {{{ + * val f = ask(worker, request)(timeout) + * flow { + * EnrichedRequest(request, f()) + * } pipeTo 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-actor/src/main/scala/akka/pattern/PipeToSupport.scala b/akka-actor/src/main/scala/akka/pattern/PipeToSupport.scala new file mode 100644 index 0000000000..6827946902 --- /dev/null +++ b/akka-actor/src/main/scala/akka/pattern/PipeToSupport.scala @@ -0,0 +1,15 @@ +/** + * Copyright (C) 2009-2011 Typesafe Inc. + */ +package akka.pattern + +import akka.actor.ActorRef +import akka.dispatch.Future + +object PipeToSupport { + + class PipeableFuture[T](val future: Future[T]) { + def pipeTo(actorRef: ActorRef): Future[T] = akka.pattern.pipeTo(future, actorRef) + } + +} \ No newline at end of file diff --git a/akka-actor/src/main/scala/akka/pattern/package.scala b/akka-actor/src/main/scala/akka/pattern/package.scala index 5bc426a67d..500beca807 100644 --- a/akka-actor/src/main/scala/akka/pattern/package.scala +++ b/akka-actor/src/main/scala/akka/pattern/package.scala @@ -69,4 +69,39 @@ package object pattern { case _ ⇒ throw new IllegalArgumentException("incompatible ActorRef " + actorRef) } + /** + * Import this implicit conversion to gain the `pipeTo` method on [[akka.dispatch.Future]]: + * + * {{{ + * import akka.pattern.pipeTo + * + * Future { doExpensiveCalc() } pipeTo nextActor + * }}} + */ + implicit def pipeTo[T](future: Future[T]): PipeToSupport.PipeableFuture[T] = new PipeToSupport.PipeableFuture(future) + + /** + * Register an onComplete callback on this [[akka.dispatch.Future]] to send + * the result to the given actor reference. Returns the original Future to + * allow method chaining. + * + * Recommended usage example: + * + * {{{ + * val f = ask(worker, request)(timeout) + * flow { + * EnrichedRequest(request, f()) + * } pipeTo nextActor + * }}} + * + * [see [[akka.dispatch.Future]] for a description of `flow`] + */ + def pipeTo[T](future: Future[T], actorRef: ActorRef): Future[T] = { + future onComplete { + case Right(r) ⇒ actorRef ! r + case Left(f) ⇒ actorRef ! akka.actor.Status.Failure(f) + } + future + } + } From 8b14cd683d0abdef0d3dae15341d0e58acd4625a Mon Sep 17 00:00:00 2001 From: Roland Date: Wed, 18 Jan 2012 13:26:11 +0100 Subject: [PATCH 11/18] scaladoc for patterns --- .../src/main/scala/akka/actor/Scheduler.scala | 4 +-- .../main/scala/akka/pattern/Patterns.scala | 3 ++ .../src/main/scala/akka/pattern/package.scala | 33 +++++++++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/akka-actor/src/main/scala/akka/actor/Scheduler.scala b/akka-actor/src/main/scala/akka/actor/Scheduler.scala index a7d4376114..8104199dec 100644 --- a/akka-actor/src/main/scala/akka/actor/Scheduler.scala +++ b/akka-actor/src/main/scala/akka/actor/Scheduler.scala @@ -27,8 +27,8 @@ trait Scheduler { /** * Schedules a message to be sent repeatedly with an initial delay and * frequency. E.g. if you would like a message to be sent immediately and - * thereafter every 500ms you would set delay = Duration.Zero and frequency - * = Duration(500, TimeUnit.MILLISECONDS) + * thereafter every 500ms you would set delay=Duration.Zero and + * frequency=Duration(500, TimeUnit.MILLISECONDS) * * Java & Scala API */ diff --git a/akka-actor/src/main/scala/akka/pattern/Patterns.scala b/akka-actor/src/main/scala/akka/pattern/Patterns.scala index 50e6bb909c..ae359ba795 100644 --- a/akka-actor/src/main/scala/akka/pattern/Patterns.scala +++ b/akka-actor/src/main/scala/akka/pattern/Patterns.scala @@ -10,6 +10,7 @@ object Patterns { import akka.util.Timeout /** + * Java API for `akka.pattern.ask`: * Sends a message asynchronously and returns a [[akka.dispatch.Future]] * holding the eventual reply message; this means that the target actor * needs to send the result to the `sender` reference provided. The Future @@ -42,6 +43,7 @@ object Patterns { def ask(actor: ActorRef, message: Any): Future[AnyRef] = scalaAsk(actor, message).asInstanceOf[Future[AnyRef]] /** + * Java API for `akka.pattern.ask`: * Sends a message asynchronously and returns a [[akka.dispatch.Future]] * holding the eventual reply message; this means that the target actor * needs to send the result to the `sender` reference provided. The Future @@ -72,6 +74,7 @@ object Patterns { def ask(actor: ActorRef, message: Any, timeout: Timeout): Future[AnyRef] = scalaAsk(actor, message)(timeout).asInstanceOf[Future[AnyRef]] /** + * Java API for `akka.pattern.ask`: * Sends a message asynchronously and returns a [[akka.dispatch.Future]] * holding the eventual reply message; this means that the target actor * needs to send the result to the `sender` reference provided. The Future diff --git a/akka-actor/src/main/scala/akka/pattern/package.scala b/akka-actor/src/main/scala/akka/pattern/package.scala index 500beca807..41cba41876 100644 --- a/akka-actor/src/main/scala/akka/pattern/package.scala +++ b/akka-actor/src/main/scala/akka/pattern/package.scala @@ -3,6 +3,39 @@ */ package akka +/** + * == Commonly Used Patterns With Akka == + * + * This package is used as a collection point for usage patterns which involve + * actors, futures, etc. but are loosely enough coupled to (multiple of) them + * to present them separately from the core implementation. Currently supported + * are: + * + *
    + *
  • ask: create a temporary one-off actor for receiving a reply to a + * message and complete a [[akka.dispatch.Future]] with it; returns said + * Future.
  • + *
  • pipeTo: feed eventually computed value of a future to an actor as + * a message.
  • + *
+ * + * In Scala the recommended usage is to import the pattern from the package + * object: + * {{{ + * import akka.pattern.ask + * + * ask(actor, message) // use it directly + * actor ask message // use it by implicit conversion + * }}} + * + * For Java the patterns are available as static methods of the [[akka.pattern.Patterns]] + * class: + * {{{ + * import static akka.pattern.Patterns.ask; + * + * ask(actor, message); + * }}} + */ package object pattern { import akka.actor.{ ActorRef, InternalActorRef, ActorRefWithProvider } From 020c6b61dac47168e961943b46abff80fb875326 Mon Sep 17 00:00:00 2001 From: Roland Date: Thu, 19 Jan 2012 15:13:10 +0100 Subject: [PATCH 12/18] move all Ask stuff to akka.pattern MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - remove ?(msg, timeout), should always use ?(msg)(timeout) because of Scala’s only Martin-acknowledged design flaw of being able to pass tuples into single-arg methods without adding another pair of parens - put a provider into all actor refs, because they all are created by and associated with one - treat all terminated refs equally: tell(msg) and return broken promise --- .../scala/akka/actor/ActorLookupSpec.scala | 10 ++-- .../test/scala/akka/actor/ActorRefSpec.scala | 11 ++-- .../scala/akka/actor/ActorTimeoutSpec.scala | 2 +- .../scala/akka/actor/SupervisorSpec.scala | 10 ++-- .../test/scala/akka/dispatch/FutureSpec.scala | 12 ++-- .../src/test/scala/akka/pattern/AskSpec.scala | 35 ++++++++++++ .../src/main/scala/akka/actor/ActorRef.scala | 57 +++++++++++++------ .../scala/akka/actor/ActorRefProvider.scala | 6 +- .../main/scala/akka/actor/ActorSystem.scala | 4 +- .../src/main/scala/akka/actor/Locker.scala | 7 ++- .../main/scala/akka/actor/TypedActor.scala | 6 +- .../src/main/scala/akka/event/Logging.scala | 1 + .../main/scala/akka/pattern/AskSupport.scala | 20 ++----- .../src/main/scala/akka/pattern/package.scala | 17 +++--- .../src/main/scala/akka/util/Duration.scala | 1 - .../src/main/scala/akka/agent/Agent.scala | 4 +- .../code/akka/docs/actor/ActorDocSpec.scala | 2 +- .../src/main/scala/akka/remote/Remote.scala | 2 +- .../akka/remote/RemoteActorRefProvider.scala | 2 +- 19 files changed, 134 insertions(+), 75 deletions(-) create mode 100644 akka-actor-tests/src/test/scala/akka/pattern/AskSpec.scala diff --git a/akka-actor-tests/src/test/scala/akka/actor/ActorLookupSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/ActorLookupSpec.scala index 135a7efe0a..f8bb976b3c 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/ActorLookupSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/ActorLookupSpec.scala @@ -40,11 +40,13 @@ class ActorLookupSpec extends AkkaSpec with DefaultTimeout { val c2 = system.actorOf(p, "c2") val c21 = Await.result((c2 ? Create("c21")).mapTo[ActorRef], timeout.duration) - val user = system.asInstanceOf[ActorSystemImpl].guardian - val syst = system.asInstanceOf[ActorSystemImpl].systemGuardian - val root = system.asInstanceOf[ActorSystemImpl].lookupRoot + val sysImpl = system.asInstanceOf[ActorSystemImpl] - def empty(path: String) = new EmptyLocalActorRef(system.eventStream, system.dispatcher, path match { + val user = sysImpl.guardian + val syst = sysImpl.systemGuardian + val root = sysImpl.lookupRoot + + def empty(path: String) = new EmptyLocalActorRef(system.eventStream, sysImpl.provider, system.dispatcher, path match { case RelativeActorPath(elems) ⇒ system.actorFor("/").path / elems }) diff --git a/akka-actor-tests/src/test/scala/akka/actor/ActorRefSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/ActorRefSpec.scala index 8dbd1c9a8c..a46b0a3a42 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/ActorRefSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/ActorRefSpec.scala @@ -288,7 +288,8 @@ class ActorRefSpec extends AkkaSpec with DefaultTimeout { val baos = new ByteArrayOutputStream(8192 * 32) val out = new ObjectOutputStream(baos) - val addr = system.asInstanceOf[ActorSystemImpl].provider.rootPath.address + val sysImpl = system.asInstanceOf[ActorSystemImpl] + val addr = sysImpl.provider.rootPath.address val serialized = SerializedActorRef(addr + "/non-existing") out.writeObject(serialized) @@ -296,9 +297,9 @@ class ActorRefSpec extends AkkaSpec with DefaultTimeout { out.flush out.close - Serialization.currentSystem.withValue(system.asInstanceOf[ActorSystemImpl]) { + Serialization.currentSystem.withValue(sysImpl) { val in = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray)) - in.readObject must be === new EmptyLocalActorRef(system.eventStream, system.dispatcher, system.actorFor("/").path / "non-existing") + in.readObject must be === new EmptyLocalActorRef(system.eventStream, sysImpl.provider, system.dispatcher, system.actorFor("/").path / "non-existing") } } @@ -359,8 +360,8 @@ class ActorRefSpec extends AkkaSpec with DefaultTimeout { } })) - val ffive = (ref ? (5, timeout)).mapTo[String] - val fnull = (ref ? (null, timeout)).mapTo[String] + val ffive = (ref.ask(5)(timeout)).mapTo[String] + val fnull = (ref.ask(null)(timeout)).mapTo[String] ref ! PoisonPill Await.result(ffive, timeout.duration) must be("five") diff --git a/akka-actor-tests/src/test/scala/akka/actor/ActorTimeoutSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/ActorTimeoutSpec.scala index d8977aa25d..dac38a7481 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/ActorTimeoutSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/ActorTimeoutSpec.scala @@ -45,7 +45,7 @@ class ActorTimeoutSpec extends AkkaSpec with BeforeAndAfterAll with DefaultTimeo "use explicitly supplied timeout" in { within(testTimeout - 100.millis, testTimeout + 300.millis) { val echo = system.actorOf(Props.empty) - val f = echo.?("hallo", testTimeout) + val f = echo.?("hallo")(testTimeout) try { intercept[AskTimeoutException] { Await.result(f, testTimeout + 300.millis) } } finally { system.stop(echo) } diff --git a/akka-actor-tests/src/test/scala/akka/actor/SupervisorSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/SupervisorSpec.scala index 73ff90c3c7..5995c47d7b 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/SupervisorSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/SupervisorSpec.scala @@ -129,12 +129,12 @@ class SupervisorSpec extends AkkaSpec with BeforeAndAfterEach with ImplicitSende } def ping(pingPongActor: ActorRef) = { - Await.result(pingPongActor.?(Ping, TimeoutMillis), TimeoutMillis millis) must be === PongMessage + Await.result(pingPongActor.?(Ping)(TimeoutMillis), TimeoutMillis millis) must be === PongMessage expectMsg(Timeout, PingMessage) } def kill(pingPongActor: ActorRef) = { - val result = (pingPongActor ? (DieReply, TimeoutMillis)) + val result = (pingPongActor.?(DieReply)(TimeoutMillis)) expectMsg(Timeout, ExceptionMessage) intercept[RuntimeException] { Await.result(result, TimeoutMillis millis) } } @@ -152,7 +152,7 @@ class SupervisorSpec extends AkkaSpec with BeforeAndAfterEach with ImplicitSende "not restart temporary actor" in { val (temporaryActor, _) = temporaryActorAllForOne - intercept[RuntimeException] { Await.result(temporaryActor.?(DieReply, TimeoutMillis), TimeoutMillis millis) } + intercept[RuntimeException] { Await.result(temporaryActor.?(DieReply)(TimeoutMillis), TimeoutMillis millis) } expectNoMsg(1 second) } @@ -298,11 +298,11 @@ class SupervisorSpec extends AkkaSpec with BeforeAndAfterEach with ImplicitSende filterEvents(EventFilter[RuntimeException]("Expected", occurrences = 1), EventFilter[IllegalStateException]("error while creating actor", occurrences = 1)) { intercept[RuntimeException] { - Await.result(dyingActor.?(DieReply, TimeoutMillis), TimeoutMillis millis) + Await.result(dyingActor.?(DieReply)(TimeoutMillis), TimeoutMillis millis) } } - Await.result(dyingActor.?(Ping, TimeoutMillis), TimeoutMillis millis) must be === PongMessage + Await.result(dyingActor.?(Ping)(TimeoutMillis), TimeoutMillis millis) must be === PongMessage inits.get must be(3) diff --git a/akka-actor-tests/src/test/scala/akka/dispatch/FutureSpec.scala b/akka-actor-tests/src/test/scala/akka/dispatch/FutureSpec.scala index 2ee7c4e6c7..44509b270f 100644 --- a/akka-actor-tests/src/test/scala/akka/dispatch/FutureSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/dispatch/FutureSpec.scala @@ -324,7 +324,7 @@ class FutureSpec extends AkkaSpec with Checkers with BeforeAndAfterAll with Defa })) } val timeout = 10000 - def futures = actors.zipWithIndex map { case (actor: ActorRef, idx: Int) ⇒ actor.?((idx, idx * 200), timeout).mapTo[Int] } + def futures = actors.zipWithIndex map { case (actor: ActorRef, idx: Int) ⇒ actor.?((idx, idx * 200))(timeout).mapTo[Int] } Await.result(Future.fold(futures)(0)(_ + _), timeout millis) must be(45) } @@ -334,7 +334,7 @@ class FutureSpec extends AkkaSpec with Checkers with BeforeAndAfterAll with Defa def receive = { case (add: Int, wait: Int) ⇒ Thread.sleep(wait); sender.tell(add) } })) } - def futures = actors.zipWithIndex map { case (actor: ActorRef, idx: Int) ⇒ actor.?((idx, idx * 200), 10000).mapTo[Int] } + def futures = actors.zipWithIndex map { case (actor: ActorRef, idx: Int) ⇒ actor.?((idx, idx * 200))(10000).mapTo[Int] } Await.result(futures.foldLeft(Future(0))((fr, fa) ⇒ for (r ← fr; a ← fa) yield (r + a)), timeout.duration) must be(45) } @@ -351,7 +351,7 @@ class FutureSpec extends AkkaSpec with Checkers with BeforeAndAfterAll with Defa })) } val timeout = 10000 - def futures = actors.zipWithIndex map { case (actor: ActorRef, idx: Int) ⇒ actor.?((idx, idx * 100), timeout).mapTo[Int] } + def futures = actors.zipWithIndex map { case (actor: ActorRef, idx: Int) ⇒ actor.?((idx, idx * 100))(timeout).mapTo[Int] } intercept[Throwable] { Await.result(Future.fold(futures)(0)(_ + _), timeout millis) }.getMessage must be("shouldFoldResultsWithException: expected") } } @@ -383,7 +383,7 @@ class FutureSpec extends AkkaSpec with Checkers with BeforeAndAfterAll with Defa })) } val timeout = 10000 - def futures = actors.zipWithIndex map { case (actor: ActorRef, idx: Int) ⇒ actor.?((idx, idx * 200), timeout).mapTo[Int] } + def futures = actors.zipWithIndex map { case (actor: ActorRef, idx: Int) ⇒ actor.?((idx, idx * 200))(timeout).mapTo[Int] } assert(Await.result(Future.reduce(futures)(_ + _), timeout millis) === 45) } @@ -400,7 +400,7 @@ class FutureSpec extends AkkaSpec with Checkers with BeforeAndAfterAll with Defa })) } val timeout = 10000 - def futures = actors.zipWithIndex map { case (actor: ActorRef, idx: Int) ⇒ actor.?((idx, idx * 100), timeout).mapTo[Int] } + def futures = actors.zipWithIndex map { case (actor: ActorRef, idx: Int) ⇒ actor.?((idx, idx * 100))(timeout).mapTo[Int] } intercept[Throwable] { Await.result(Future.reduce(futures)(_ + _), timeout millis) }.getMessage must be === "shouldFoldResultsWithException: expected" } } @@ -441,7 +441,7 @@ class FutureSpec extends AkkaSpec with Checkers with BeforeAndAfterAll with Defa "shouldHandleThrowables" in { class ThrowableTest(m: String) extends Throwable(m) - filterException[ThrowableTest] { + EventFilter[ThrowableTest](occurrences = 4) intercept { val f1 = Future[Any] { throw new ThrowableTest("test") } intercept[ThrowableTest] { Await.result(f1, timeout.duration) } diff --git a/akka-actor-tests/src/test/scala/akka/pattern/AskSpec.scala b/akka-actor-tests/src/test/scala/akka/pattern/AskSpec.scala new file mode 100644 index 0000000000..44cdd91eba --- /dev/null +++ b/akka-actor-tests/src/test/scala/akka/pattern/AskSpec.scala @@ -0,0 +1,35 @@ +/** + * Copyright (C) 2009-2012 Typesafe Inc. + */ +package akka.pattern + +import akka.testkit.AkkaSpec + +class AskSpec extends AkkaSpec { + + "The “ask” pattern" must { + + "return broken promises on DeadLetters" in { + val dead = system.actorFor("/system/deadLetters") + val f = dead ask 42 + f.isCompleted must be(true) + f.value.get match { + case Left(_: AskTimeoutException) ⇒ + case v ⇒ fail(v + " was not Left(AskTimeoutException)") + } + } + + "return broken promises on EmptyLocalActorRefs" in { + val empty = system.actorFor("unknown") + implicit val timeout = system.settings.ActorTimeout + val f = empty ? 3.14 + f.isCompleted must be(true) + f.value.get match { + case Left(_: AskTimeoutException) ⇒ + case v ⇒ fail(v + " was not Left(AskTimeoutException)") + } + } + + } + +} \ No newline at end of file diff --git a/akka-actor/src/main/scala/akka/actor/ActorRef.scala b/akka-actor/src/main/scala/akka/actor/ActorRef.scala index 5d07a662b3..cbb21bff78 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorRef.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorRef.scala @@ -167,13 +167,6 @@ trait LocalRef extends ActorRefScope { final def isLocal = true } -/** - * Trait for matching on ActorRefs which have access to a provider; this is used in akka.pattern.ask. - */ -trait ActorRefWithProvider { this: InternalActorRef ⇒ - def provider: ActorRefProvider -} - /** * Internal trait for assembling all the functionality needed internally on * ActorRefs. NOTE THAT THIS IS NOT A STABLE EXTERNAL INTERFACE! @@ -181,12 +174,25 @@ trait ActorRefWithProvider { this: InternalActorRef ⇒ * DO NOT USE THIS UNLESS INTERNALLY WITHIN AKKA! */ private[akka] abstract class InternalActorRef extends ActorRef with ScalaActorRef { this: ActorRefScope ⇒ + /* + * Actor life-cycle management, invoked only internally (in response to user requests via ActorContext). + */ def resume(): Unit def suspend(): Unit def restart(cause: Throwable): Unit def stop(): Unit def sendSystemMessage(message: SystemMessage): Unit + + /** + * Get a reference to the actor ref provider which created this ref. + */ + def provider: ActorRefProvider + + /** + * Obtain parent of this ref; used by getChild for ".." paths. + */ def getParent: InternalActorRef + /** * Obtain ActorRef by possibly traversing the actor tree or looking it up at * some provider-specific location. This method shall return the end result, @@ -196,6 +202,7 @@ private[akka] abstract class InternalActorRef extends ActorRef with ScalaActorRe * exist, return Nobody. */ def getChild(name: Iterator[String]): InternalActorRef + /** * Scope: if this ref points to an actor which resides within the same JVM, * i.e. whose mailbox is directly reachable etc. @@ -203,8 +210,12 @@ private[akka] abstract class InternalActorRef extends ActorRef with ScalaActorRe def isLocal: Boolean } +/** + * This is an internal look-up failure token, not useful for anything else. + */ private[akka] case object Nobody extends MinimalActorRef { val path = new RootActorPath(new LocalAddress("all-systems"), "/Nobody") + def provider = throw new UnsupportedOperationException("Nobody does not provide") } /** @@ -218,7 +229,7 @@ private[akka] class LocalActorRef private[akka] ( val systemService: Boolean = false, _receiveTimeout: Option[Duration] = None, _hotswap: Stack[PartialFunction[Any, Unit]] = Props.noHotSwap) - extends InternalActorRef with LocalRef with ActorRefWithProvider { + extends InternalActorRef with LocalRef { /* * actorCell.start() publishes actorCell & this to the dispatcher, which @@ -371,8 +382,9 @@ trait MinimalActorRef extends InternalActorRef with LocalRef { } object MinimalActorRef { - def apply(_path: ActorPath)(receive: PartialFunction[Any, Unit]): ActorRef = new MinimalActorRef { + def apply(_path: ActorPath, _provider: ActorRefProvider)(receive: PartialFunction[Any, Unit]): ActorRef = new MinimalActorRef { def path = _path + def provider = _provider override def !(message: Any)(implicit sender: ActorRef = null): Unit = if (receive.isDefinedAt(message)) receive(message) } @@ -393,8 +405,6 @@ trait DeadLetterActorRefLike extends MinimalActorRef { def eventStream: EventStream - @volatile - private var brokenPromise: Future[Any] = _ @volatile private var _path: ActorPath = _ def path: ActorPath = { @@ -402,9 +412,13 @@ trait DeadLetterActorRefLike extends MinimalActorRef { _path } - private[akka] def init(dispatcher: MessageDispatcher, path: ActorPath) { + @volatile + private var _provider: ActorRefProvider = _ + def provider = _provider + + private[akka] def init(provider: ActorRefProvider, path: ActorPath) { _path = path - brokenPromise = Promise.failed(new ActorKilledException("In DeadLetterActorRef - promises are always broken."))(dispatcher) + _provider = provider } override def isTerminated(): Boolean = true @@ -426,16 +440,25 @@ class DeadLetterActorRef(val eventStream: EventStream) extends DeadLetterActorRe * This special dead letter reference has a name: it is that which is returned * by a local look-up which is unsuccessful. */ -class EmptyLocalActorRef(val eventStream: EventStream, _dispatcher: MessageDispatcher, _path: ActorPath) - extends DeadLetterActorRefLike { - init(_dispatcher, _path) +class EmptyLocalActorRef( + val eventStream: EventStream, + _provider: ActorRefProvider, + _dispatcher: MessageDispatcher, + _path: ActorPath) extends DeadLetterActorRefLike { + + init(_provider, _path) + override def !(message: Any)(implicit sender: ActorRef = null): Unit = message match { case d: DeadLetter ⇒ // do NOT form endless loops case _ ⇒ eventStream.publish(DeadLetter(message, sender, this)) } } -class VirtualPathContainer(val path: ActorPath, override val getParent: InternalActorRef, val log: LoggingAdapter) extends MinimalActorRef { +class VirtualPathContainer( + val provider: ActorRefProvider, + val path: ActorPath, + override val getParent: InternalActorRef, + val log: LoggingAdapter) extends MinimalActorRef { private val children = new ConcurrentHashMap[String, InternalActorRef] diff --git a/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala b/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala index 86673d259b..767309d6e0 100755 --- a/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala @@ -324,6 +324,8 @@ class LocalActorRefProvider( val path = rootPath / "bubble-walker" + def provider: ActorRefProvider = LocalActorRefProvider.this + override def stop() = stopped switchOn { terminationFuture.complete(causeOfTermination.toLeft(())) } @@ -440,7 +442,7 @@ class LocalActorRefProvider( lazy val systemGuardian: InternalActorRef = actorOf(system, guardianProps.withCreator(new SystemGuardian), rootGuardian, rootPath / "system", true, None) - lazy val tempContainer = new VirtualPathContainer(tempNode, rootGuardian, log) + lazy val tempContainer = new VirtualPathContainer(system.provider, tempNode, rootGuardian, log) def registerTempActor(actorRef: InternalActorRef, path: ActorPath): Unit = { assert(path.parent eq tempNode, "cannot registerTempActor() with anything not obtained from tempPath()") @@ -489,7 +491,7 @@ class LocalActorRefProvider( } else ref.getChild(path.iterator) match { case Nobody ⇒ log.debug("look-up of path sequence '{}' failed", path) - new EmptyLocalActorRef(eventStream, dispatcher, ref.path / path) + new EmptyLocalActorRef(eventStream, system.provider, dispatcher, ref.path / path) case x ⇒ x } diff --git a/akka-actor/src/main/scala/akka/actor/ActorSystem.scala b/akka-actor/src/main/scala/akka/actor/ActorSystem.scala index 04084e2c2c..8ff4ebe373 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorSystem.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorSystem.scala @@ -377,10 +377,10 @@ class ActorSystemImpl(val name: String, applicationConfig: Config) extends Actor // the provider is expected to start default loggers, LocalActorRefProvider does this provider.init(this) _log = new BusLogging(eventStream, "ActorSystem(" + lookupRoot.path.address + ")", this.getClass) - deadLetters.init(dispatcher, lookupRoot.path / "deadLetters") + deadLetters.init(provider, lookupRoot.path / "deadLetters") // this starts the reaper actor and the user-configured logging subscribers, which are also actors registerOnTermination(stopScheduler()) - _locker = new Locker(scheduler, ReaperInterval, lookupRoot.path / "locker", deathWatch) + _locker = new Locker(scheduler, ReaperInterval, provider, lookupRoot.path / "locker", deathWatch) loadExtensions() if (LogConfigOnStart) logConfiguration() this diff --git a/akka-actor/src/main/scala/akka/actor/Locker.scala b/akka-actor/src/main/scala/akka/actor/Locker.scala index d4fd1badd5..ee6ea0c344 100644 --- a/akka-actor/src/main/scala/akka/actor/Locker.scala +++ b/akka-actor/src/main/scala/akka/actor/Locker.scala @@ -9,7 +9,12 @@ import akka.util.duration._ import java.util.concurrent.ConcurrentHashMap import akka.event.DeathWatch -class Locker(scheduler: Scheduler, period: Duration, val path: ActorPath, val deathWatch: DeathWatch) extends MinimalActorRef { +class Locker( + scheduler: Scheduler, + period: Duration, + val provider: ActorRefProvider, + val path: ActorPath, + val deathWatch: DeathWatch) extends MinimalActorRef { class DavyJones extends Runnable { def run = { diff --git a/akka-actor/src/main/scala/akka/actor/TypedActor.scala b/akka-actor/src/main/scala/akka/actor/TypedActor.scala index ccb5819074..8bc457904e 100644 --- a/akka-actor/src/main/scala/akka/actor/TypedActor.scala +++ b/akka-actor/src/main/scala/akka/actor/TypedActor.scala @@ -335,15 +335,15 @@ object TypedActor extends ExtensionId[TypedActorExtension] with ExtensionIdProvi import akka.pattern.ask MethodCall(method, args) match { case m if m.isOneWay ⇒ actor ! m; null //Null return value - case m if m.returnsFuture_? ⇒ actor.?(m, timeout) + case m if m.returnsFuture_? ⇒ ask(actor, m)(timeout) case m if m.returnsJOption_? || m.returnsOption_? ⇒ - val f = actor.?(m, timeout) + val f = ask(actor, m)(timeout) (try { Await.ready(f, timeout.duration).value } catch { case _: TimeoutException ⇒ None }) match { case None | Some(Right(null)) ⇒ if (m.returnsJOption_?) JOption.none[Any] else None case Some(Right(joption: AnyRef)) ⇒ joption case Some(Left(ex)) ⇒ throw ex } - case m ⇒ Await.result(actor.?(m, timeout), timeout.duration).asInstanceOf[AnyRef] + case m ⇒ Await.result(ask(actor, m)(timeout), timeout.duration).asInstanceOf[AnyRef] } } } diff --git a/akka-actor/src/main/scala/akka/event/Logging.scala b/akka-actor/src/main/scala/akka/event/Logging.scala index 854ac625ab..cb8f9df29e 100644 --- a/akka-actor/src/main/scala/akka/event/Logging.scala +++ b/akka-actor/src/main/scala/akka/event/Logging.scala @@ -649,6 +649,7 @@ object Logging { */ class StandardOutLogger extends MinimalActorRef with StdOutLogger { val path: ActorPath = new RootActorPath(LocalAddress("all-systems"), "/StandardOutLogger") + def provider: ActorRefProvider = throw new UnsupportedOperationException("StandardOutLogger does not provide") override val toString = "StandardOutLogger" override def !(message: Any)(implicit sender: ActorRef = null): Unit = print(message) } diff --git a/akka-actor/src/main/scala/akka/pattern/AskSupport.scala b/akka-actor/src/main/scala/akka/pattern/AskSupport.scala index bc79877fc3..ca07ea5052 100644 --- a/akka-actor/src/main/scala/akka/pattern/AskSupport.scala +++ b/akka-actor/src/main/scala/akka/pattern/AskSupport.scala @@ -51,7 +51,7 @@ object AskSupport { * * [see the [[akka.dispatch.Future]] companion object for a description of `flow`] */ - def ask(message: AnyRef)(implicit timeout: Timeout): Future[Any] = akka.pattern.ask(actorRef, message)(timeout) + def ask(message: Any)(implicit timeout: Timeout = null): Future[Any] = akka.pattern.ask(actorRef, message)(timeout) /** * Sends a message asynchronously and returns a [[akka.dispatch.Future]] @@ -81,20 +81,7 @@ object AskSupport { * * [see the [[akka.dispatch.Future]] companion object for a description of `flow`] */ - def ?(message: Any)(implicit timeout: Timeout): Future[Any] = akka.pattern.ask(actorRef, message) - - /* - * FIXME: I think this should be removed, since it introduces an “ambiguity” - * when sending Tuple2, which the compiler resolves unexpectedly to this - * method; also overloading is bad, isn’t it? - RK (ticket #1653) - */ - /** - * Sends a message asynchronously, returning a future which may eventually hold the reply. - * The implicit parameter with the default value is just there to disambiguate it from the version that takes the - * implicit timeout - */ - def ?(message: Any, timeout: Timeout)(implicit ignore: Int = 0): Future[Any] = ?(message)(timeout) - + def ?(message: Any)(implicit timeout: Timeout): Future[Any] = akka.pattern.ask(actorRef, message)(timeout) } /** @@ -102,6 +89,7 @@ object AskSupport { * receive the reply to an "ask" operation. */ private[akka] final class PromiseActorRef( + val provider: ActorRefProvider, val path: ActorPath, override val getParent: InternalActorRef, val result: Promise[Any], @@ -130,7 +118,7 @@ object AskSupport { def createAsker(provider: ActorRefProvider, timeout: Timeout): PromiseActorRef = { val path = provider.tempPath() val result = Promise[Any]()(provider.dispatcher) - val a = new PromiseActorRef(path, provider.tempContainer, result, provider.deathWatch) + val a = new PromiseActorRef(provider, path, provider.tempContainer, result, provider.deathWatch) provider.registerTempActor(a, path) val f = provider.scheduler.scheduleOnce(timeout.duration) { result.failure(new AskTimeoutException("Timed out")) } result onComplete { _ ⇒ diff --git a/akka-actor/src/main/scala/akka/pattern/package.scala b/akka-actor/src/main/scala/akka/pattern/package.scala index 6aaff00fd4..4abb7c41d7 100644 --- a/akka-actor/src/main/scala/akka/pattern/package.scala +++ b/akka-actor/src/main/scala/akka/pattern/package.scala @@ -3,6 +3,10 @@ */ package akka +import akka.actor._ +import akka.dispatch.{ Future, Promise } +import akka.util.{ Timeout, Duration } + /** * == Commonly Used Patterns With Akka == * @@ -38,10 +42,6 @@ package akka */ package object pattern { - import akka.actor._ - import akka.dispatch.{ Future, Promise } - import akka.util.{ Timeout, Duration } - /** * Import this implicit conversion to gain `?` and `ask` methods on * [[akka.actor.ActorRef]], which will defer to the @@ -88,12 +88,15 @@ package object pattern { * [see [[akka.dispatch.Future]] for a description of `flow`] */ def ask(actorRef: ActorRef, message: Any)(implicit timeout: Timeout = null): Future[Any] = actorRef match { - case ref: ActorRefWithProvider ⇒ + case ref: InternalActorRef if ref.isTerminated ⇒ + actorRef.tell(message) + Promise.failed(new AskTimeoutException("sending to terminated ref breaks promises"))(ref.provider.dispatcher) + case ref: InternalActorRef ⇒ val provider = ref.provider (if (timeout == null) provider.settings.ActorTimeout else timeout) match { case t if t.duration.length <= 0 ⇒ actorRef.tell(message) - Promise.failed(new AskTimeoutException("failed to create PromiseActorRef"))(provider.dispatcher) + Promise.failed(new AskTimeoutException("not asking with negative timeout"))(provider.dispatcher) case t ⇒ val a = AskSupport.createAsker(provider, t) actorRef.tell(message, a) @@ -132,7 +135,7 @@ package object pattern { def pipeTo[T](future: Future[T], actorRef: ActorRef): Future[T] = { future onComplete { case Right(r) ⇒ actorRef ! r - case Left(f) ⇒ actorRef ! akka.actor.Status.Failure(f) + case Left(f) ⇒ actorRef ! Status.Failure(f) } future } diff --git a/akka-actor/src/main/scala/akka/util/Duration.scala b/akka-actor/src/main/scala/akka/util/Duration.scala index 1406ad8564..1442d907d7 100644 --- a/akka-actor/src/main/scala/akka/util/Duration.scala +++ b/akka-actor/src/main/scala/akka/util/Duration.scala @@ -568,4 +568,3 @@ object Timeout { implicit def intToTimeout(timeout: Int) = new Timeout(timeout) implicit def longToTimeout(timeout: Long) = new Timeout(timeout) } - diff --git a/akka-agent/src/main/scala/akka/agent/Agent.scala b/akka-agent/src/main/scala/akka/agent/Agent.scala index cd19a0c781..8778d95760 100644 --- a/akka-agent/src/main/scala/akka/agent/Agent.scala +++ b/akka-agent/src/main/scala/akka/agent/Agent.scala @@ -124,7 +124,7 @@ class Agent[T](initialValue: T, system: ActorSystem) { * that new state can be obtained within the given timeout. */ def alter(f: T ⇒ T)(timeout: Timeout): Future[T] = { - def dispatch = updater.?(Alter(f), timeout).asInstanceOf[Future[T]] + def dispatch = ask(updater, Alter(f))(timeout).asInstanceOf[Future[T]] val txn = Txn.findCurrent if (txn.isDefined) { val result = Promise[T]()(system.dispatcher) @@ -172,7 +172,7 @@ class Agent[T](initialValue: T, system: ActorSystem) { send((value: T) ⇒ { suspend() val threadBased = system.actorOf(Props(new ThreadBasedAgentUpdater(this)).withDispatcher("akka.agent.alter-off-dispatcher")) - result completeWith threadBased.?(Alter(f), timeout).asInstanceOf[Future[T]] + result completeWith ask(threadBased, Alter(f))(timeout).asInstanceOf[Future[T]] value }) result diff --git a/akka-docs/scala/code/akka/docs/actor/ActorDocSpec.scala b/akka-docs/scala/code/akka/docs/actor/ActorDocSpec.scala index bb82aab595..a753325429 100644 --- a/akka-docs/scala/code/akka/docs/actor/ActorDocSpec.scala +++ b/akka-docs/scala/code/akka/docs/actor/ActorDocSpec.scala @@ -252,7 +252,7 @@ class ActorDocSpec extends AkkaSpec(Map("akka.loglevel" -> "INFO")) { //#using-explicit-timeout import akka.util.duration._ import akka.pattern.ask - val future = myActor ? ("hello", timeout = 500 millis) + val future = myActor.ask("hello")(500 millis) //#using-explicit-timeout Await.result(future, 500 millis) must be("hello") } diff --git a/akka-remote/src/main/scala/akka/remote/Remote.scala b/akka-remote/src/main/scala/akka/remote/Remote.scala index f76aa8e908..628f9aea97 100644 --- a/akka-remote/src/main/scala/akka/remote/Remote.scala +++ b/akka-remote/src/main/scala/akka/remote/Remote.scala @@ -124,7 +124,7 @@ case class DaemonMsgWatch(watcher: ActorRef, watched: ActorRef) extends DaemonMs * It acts as the brain of the remote that responds to system remote events (messages) and undertakes action. */ class RemoteSystemDaemon(system: ActorSystemImpl, remote: Remote, _path: ActorPath, _parent: InternalActorRef, _log: LoggingAdapter) - extends VirtualPathContainer(_path, _parent, _log) { + extends VirtualPathContainer(system.provider, _path, _parent, _log) { /** * Find the longest matching path which we know about and return that ref diff --git a/akka-remote/src/main/scala/akka/remote/RemoteActorRefProvider.scala b/akka-remote/src/main/scala/akka/remote/RemoteActorRefProvider.scala index a04d37e207..388007ae33 100644 --- a/akka-remote/src/main/scala/akka/remote/RemoteActorRefProvider.scala +++ b/akka-remote/src/main/scala/akka/remote/RemoteActorRefProvider.scala @@ -166,7 +166,7 @@ private[akka] class RemoteActorRef private[akka] ( val path: ActorPath, val getParent: InternalActorRef, loader: Option[ClassLoader]) - extends InternalActorRef with RemoteRef with ActorRefWithProvider { + extends InternalActorRef with RemoteRef { def getChild(name: Iterator[String]): InternalActorRef = { val s = name.toStream From 1f99b425de2eaf91a143235bdf890b50dd26db2e Mon Sep 17 00:00:00 2001 From: Roland Date: Fri, 20 Jan 2012 18:09:26 +0100 Subject: [PATCH 13/18] docs for ask/pipeTo patterns --- .../docs/actor/UntypedActorDocTestBase.java | 50 +++++++++++++++++ akka-docs/java/untyped-actors.rst | 40 +++++++------- akka-docs/scala/actors.rst | 53 +++++++++---------- .../code/akka/docs/actor/ActorDocSpec.scala | 46 ++++++++-------- .../src/main/scala/akka/remote/Gossiper.scala | 2 +- 5 files changed, 119 insertions(+), 72 deletions(-) diff --git a/akka-docs/java/code/akka/docs/actor/UntypedActorDocTestBase.java b/akka-docs/java/code/akka/docs/actor/UntypedActorDocTestBase.java index 676254425e..054495b390 100644 --- a/akka-docs/java/code/akka/docs/actor/UntypedActorDocTestBase.java +++ b/akka-docs/java/code/akka/docs/actor/UntypedActorDocTestBase.java @@ -37,6 +37,17 @@ import akka.util.Duration; import akka.actor.ActorTimeoutException; //#import-gracefulStop +//#import-askPipeTo +import static akka.pattern.Patterns.ask; +import static akka.pattern.Patterns.pipeTo; +import akka.dispatch.Future; +import akka.dispatch.Futures; +import akka.util.Duration; +import akka.util.Timeout; +import java.util.concurrent.TimeUnit; +import java.util.ArrayList; +//#import-askPipeTo + import akka.actor.Props; import akka.actor.UntypedActor; import akka.actor.UntypedActorFactory; @@ -45,6 +56,8 @@ import akka.dispatch.MessageDispatcher; import org.junit.Test; import scala.Option; import java.lang.Object; +import java.util.ArrayList; +import java.util.Iterator; import java.util.concurrent.TimeUnit; import akka.pattern.Patterns; @@ -198,6 +211,43 @@ public class UntypedActorDocTestBase { //#gracefulStop system.shutdown(); } + + class Result { + final int x; + final String s; + public Result(int x, String s) { + this.x = x; + this.s = s; + } + } + + @Test + public void usePatternsAskPipeTo() { + ActorSystem system = ActorSystem.create("MySystem"); + ActorRef actorA = system.actorOf(new Props(MyUntypedActor.class)); + ActorRef actorB = system.actorOf(new Props(MyUntypedActor.class)); + ActorRef actorC = system.actorOf(new Props(MyUntypedActor.class)); + //#ask-pipeTo + final Timeout t = new Timeout(Duration.create(5, TimeUnit.SECONDS)); + + final ArrayList> futures = new ArrayList>(); + futures.add(ask(actorA, "request")); // using `akka.actor.timeout` from config + futures.add(ask(actorB, "reqeest", t)); // using explicit timeout from above + + final Future> aggregate = Futures.sequence(futures, system.dispatcher()); + + final Future transformed = aggregate.map(new akka.japi.Function, Result>() { + public Result apply(Iterable coll) { + final Iterator it = coll.iterator(); + final String s = (String) it.next(); + final int x = (Integer) it.next(); + return new Result(x, s); + } + }); + + pipeTo(transformed, actorC); + //#ask-pipeTo + } public static class MyActor extends UntypedActor { diff --git a/akka-docs/java/untyped-actors.rst b/akka-docs/java/untyped-actors.rst index 7e0d788590..b2978f7095 100644 --- a/akka-docs/java/untyped-actors.rst +++ b/akka-docs/java/untyped-actors.rst @@ -315,26 +315,37 @@ If invoked without the sender parameter the sender will be Ask: Send-And-Receive-Future ---------------------------- -Using ``?`` will send a message to the receiving Actor asynchronously and -will immediately return a :class:`Future` which will be completed with -an ``akka.actor.AskTimeoutException`` after the specified timeout: +The ``ask`` pattern involves actors as well as futures, hence it is offered as +a use pattern rather than a method on :class:`ActorRef`: -.. code-block:: java +.. includecode:: code/akka/docs/actor/UntypedActorDocTestBase.java#import-askPipeTo - long timeoutMillis = 1000; - Future future = actorRef.ask("Hello", timeoutMillis); +.. includecode:: code/akka/docs/actor/UntypedActorDocTestBase.java#ask-pipeTo -The receiving actor should reply to this message, which will complete the -future with the reply message as value; ``getSender.tell(result)``. +This example demonstrates ``ask`` together with the ``pipeTo`` pattern on +futures, because this is likely to be a common combination. Please note that +all of the above is completely non-blocking and asynchronous: ``ask`` produces +a :class:`Future`, two of which are composed into a new future using the +:meth:`Futures.sequence` and :meth:`map` methods and then ``pipeTo`` installs +an ``onComplete``-handler on the future to effect the submission of the +aggregated :class:`Result` to another actor. + +Using ``ask`` will send a message to the receiving Actor as with ``tell``, and +the receiving actor must reply with ``getSender().tell(reply)`` in order to +complete the returned :class:`Future` with a value. The ``ask`` operation +involves creating an internal actor for handling this reply, which needs to +have a timeout after which it is destroyed in order not to leak resources; see +more below. To complete the future with an exception you need send a Failure message to the sender. -This is not done automatically when an actor throws an exception while processing a +This is *not done automatically* when an actor throws an exception while processing a message. .. includecode:: code/akka/docs/actor/UntypedActorDocTestBase.java#reply-exception If the actor does not complete the future, it will expire after the timeout period, -specified as parameter to the ``ask`` method. +specified as parameter to the ``ask`` method; this will complete the +:class:`Future` with an :class:`AskTimeoutException`. See :ref:`futures-java` for more information on how to await or query a future. @@ -353,15 +364,6 @@ Gives you a way to avoid blocking. there is not yet a way to detect these illegal accesses at compile time. See also: :ref:`jmm-shared-state` -The future returned from the ``ask`` method can conveniently be passed around or -chained with further processing steps, but sometimes you just need the value, -even if that entails waiting for it (but keep in mind that waiting inside an -actor is prone to dead-locks, e.g. if obtaining the result depends on -processing another message on this actor). - -.. includecode:: code/akka/docs/actor/UntypedActorDocTestBase.java - :include: import-future,using-ask - Forward message --------------- diff --git a/akka-docs/scala/actors.rst b/akka-docs/scala/actors.rst index 558b50fac8..da0ae5b91e 100644 --- a/akka-docs/scala/actors.rst +++ b/akka-docs/scala/actors.rst @@ -325,9 +325,9 @@ Send messages Messages are sent to an Actor through one of the following methods. * ``!`` means “fire-and-forget”, e.g. send a message asynchronously and return - immediately. Also know as ``tell``. + immediately. Also known as ``tell``. * ``?`` sends a message asynchronously and returns a :class:`Future` - representing a possible reply. Also know as ``ask``. + representing a possible reply. Also known as ``ask``. Message ordering is guaranteed on a per-sender basis. @@ -352,25 +352,34 @@ If invoked from an instance that is **not** an Actor the sender will be Ask: Send-And-Receive-Future ---------------------------- -Using ``?`` will send a message to the receiving Actor asynchronously and -will immediately return a :class:`Future` which will be completed with -an ``akka.actor.AskTimeoutException`` after the specified timeout: +The ``ask`` pattern involves actors as well as futures, hence it is offered as +a use pattern rather than a method on :class:`ActorRef`: -.. code-block:: scala +.. includecode:: code/akka/docs/actor/ActorDocSpec.scala#ask-pipeTo - val future = actor ? "hello" +This example demonstrates ``ask`` together with the ``pipeTo`` pattern on +futures, because this is likely to be a common combination. Please note that +all of the above is completely non-blocking and asynchronous: ``ask`` produces +a :class:`Future`, three of which are composed into a new future using the +for-comprehension and then ``pipeTo`` installs an ``onComplete``-handler on the +future to effect the submission of the aggregated :class:`Result` to another +actor. -The receiving actor should reply to this message, which will complete the -future with the reply message as value; ``sender ! result``. +Using ``ask`` will send a message to the receiving Actor as with ``tell``, and +the receiving actor must reply with ``sender ! reply`` in order to complete the +returned :class:`Future` with a value. The ``ask`` operation involves creating +an internal actor for handling this reply, which needs to have a timeout after +which it is destroyed in order not to leak resources; see more below. To complete the future with an exception you need send a Failure message to the sender. -This is not done automatically when an actor throws an exception while processing a +This is *not done automatically* when an actor throws an exception while processing a message. .. includecode:: code/akka/docs/actor/ActorDocSpec.scala#reply-exception -If the actor does not complete the future, it will expire after the timeout period, -which is taken from one of the following locations in order of precedence: +If the actor does not complete the future, it will expire after the timeout +period, completing it with an :class:`AskTimeoutException`. The timeout is +taken from one of the following locations in order of precedence: 1. explicitly given timeout as in: @@ -380,6 +389,9 @@ which is taken from one of the following locations in order of precedence: .. includecode:: code/akka/docs/actor/ActorDocSpec.scala#using-implicit-timeout +3. actor system’s default value from ``akka.actor.timeout`` setting for + :meth:`ask` methods + See :ref:`futures-scala` for more information on how to await or query a future. @@ -398,23 +410,6 @@ Gives you a way to avoid blocking. there is not yet a way to detect these illegal accesses at compile time. See also: :ref:`jmm-shared-state` -The future returned from the ``?`` method can conveniently be passed around or -chained with further processing steps, but sometimes you just need the value, -even if that entails waiting for it (but keep in mind that waiting inside an -actor is prone to dead-locks, e.g. if obtaining the result depends on -processing another message on this actor). - -For this purpose, there is the method :meth:`Future.as[T]` which waits until -either the future is completed or its timeout expires, whichever comes first. -The result is then inspected and returned as :class:`Some[T]` if it was -normally completed and the answer’s runtime type matches the desired type; if -the future contains an exception or the value cannot be cast to the desired -type, it will throw the exception or a :class:`ClassCastException` (if you want -to get :obj:`None` in the latter case, use :meth:`Future.asSilently[T]`). In -case of a timeout, :obj:`None` is returned. - -.. includecode:: code/akka/docs/actor/ActorDocSpec.scala#using-ask - Forward message --------------- diff --git a/akka-docs/scala/code/akka/docs/actor/ActorDocSpec.scala b/akka-docs/scala/code/akka/docs/actor/ActorDocSpec.scala index a753325429..e2bef1776f 100644 --- a/akka-docs/scala/code/akka/docs/actor/ActorDocSpec.scala +++ b/akka-docs/scala/code/akka/docs/actor/ActorDocSpec.scala @@ -212,28 +212,6 @@ class ActorDocSpec extends AkkaSpec(Map("akka.loglevel" -> "INFO")) { system.stop(myActor) } - "using ask" in { - //#using-ask - import akka.pattern.ask - - class MyActor extends Actor { - def receive = { - case x: String ⇒ sender ! x.toUpperCase - case n: Int ⇒ sender ! (n + 1) - } - } - - val myActor = system.actorOf(Props(new MyActor), name = "myactor") - implicit val timeout = system.settings.ActorTimeout - val future = ask(myActor, "hello") - for (x ← future) println(x) //Prints "hello" - - val result: Future[Int] = for (x ← ask(myActor, 3).mapTo[Int]) yield { 2 * x } - //#using-ask - - system.stop(myActor) - } - "using implicit timeout" in { val myActor = system.actorOf(Props(new FirstActor)) //#using-implicit-timeout @@ -331,6 +309,28 @@ class ActorDocSpec extends AkkaSpec(Map("akka.loglevel" -> "INFO")) { case e: ActorTimeoutException ⇒ // the actor wasn't stopped within 5 seconds } //#gracefulStop - } + + "using pattern ask / pipeTo" in { + val actorA, actorB, actorC, actorD = system.actorOf(Props.empty) + //#ask-pipeTo + import akka.pattern.{ ask, pipeTo } + + case class Result(x: Int, s: String, d: Double) + case object Request + + implicit val timeout = Timeout(5 seconds) // needed for `?` below + + val f: Future[Result] = + for { + x ← ask(actorA, Request).mapTo[Int] // call pattern directly + s ← actorB ask Request mapTo manifest[String] // call by implicit conversion + d ← actorC ? Request mapTo manifest[Double] // call by symbolic name + } yield Result(x, s, d) + + f pipeTo actorD // .. or .. + pipeTo(f, actorD) + //#ask-pipeTo + } + } diff --git a/akka-remote/src/main/scala/akka/remote/Gossiper.scala b/akka-remote/src/main/scala/akka/remote/Gossiper.scala index 788e86bb1c..74de988c59 100644 --- a/akka-remote/src/main/scala/akka/remote/Gossiper.scala +++ b/akka-remote/src/main/scala/akka/remote/Gossiper.scala @@ -252,7 +252,7 @@ class Gossiper(remote: Remote, system: ActorSystemImpl) { try { val t = remoteSettings.RemoteSystemDaemonAckTimeout - Await.result(connection ? (newGossip, t), t) match { + Await.result(connection.?(newGossip)(t), t) match { case Success(receiver) ⇒ log.debug("Gossip sent to [{}] was successfully received", receiver) case Failure(cause) ⇒ log.error(cause, cause.toString) } From f6d71881ea74bdce9ce75e334070fb2a586b497f Mon Sep 17 00:00:00 2001 From: Roland Date: Fri, 20 Jan 2012 19:45:23 +0100 Subject: [PATCH 14/18] add ?(msg, timeout) migration helper, see #1653 --- .../akka/migration/AskableActorRef.scala | 74 +++++++++++++++++++ .../main/scala/akka/migration/package.scala | 3 + .../main/scala/akka/pattern/AskSupport.scala | 2 +- .../project/migration-guide-1.3.x-2.0.x.rst | 20 +++++ 4 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 akka-actor-migration/src/main/scala/akka/migration/AskableActorRef.scala diff --git a/akka-actor-migration/src/main/scala/akka/migration/AskableActorRef.scala b/akka-actor-migration/src/main/scala/akka/migration/AskableActorRef.scala new file mode 100644 index 0000000000..caf8921812 --- /dev/null +++ b/akka-actor-migration/src/main/scala/akka/migration/AskableActorRef.scala @@ -0,0 +1,74 @@ +/** + * Copyright (C) 2009-2012 Typesafe Inc. + */ +package akka.migration + +import akka.actor.ActorRef +import akka.dispatch.Future +import akka.util.Timeout + +class AskableActorRef(val actorRef: ActorRef) { + + /** + * Sends a message asynchronously and returns a [[akka.dispatch.Future]] + * holding the eventual reply message; this means that the target actor + * needs to send the result to the `sender` reference provided. The Future + * will be completed with an [[akka.actor.AskTimeoutException]] after the + * given timeout has expired; this is independent from any timeout applied + * while awaiting a result for this future (i.e. in + * `Await.result(..., timeout)`). + * + * Warning: + * When using future callbacks, inside actors you need to carefully avoid closing over + * the containing actor’s object, i.e. do not call methods or access mutable state + * on the enclosing actor from within the callback. This would break the actor + * encapsulation and may introduce synchronization bugs and race conditions because + * the callback will be scheduled concurrently to the enclosing actor. Unfortunately + * there is not yet a way to detect these illegal accesses at compile time. + * + * Recommended usage: + * + * {{{ + * val f = worker.ask(request)(timeout) + * flow { + * EnrichedRequest(request, f()) + * } pipeTo nextActor + * }}} + * + * [see the [[akka.dispatch.Future]] companion object for a description of `flow`] + */ + def ask(message: Any)(implicit timeout: Timeout = null): Future[Any] = akka.pattern.ask(actorRef, message)(timeout) + + /** + * Sends a message asynchronously and returns a [[akka.dispatch.Future]] + * holding the eventual reply message; this means that the target actor + * needs to send the result to the `sender` reference provided. The Future + * will be completed with an [[akka.actor.AskTimeoutException]] after the + * given timeout has expired; this is independent from any timeout applied + * while awaiting a result for this future (i.e. in + * `Await.result(..., timeout)`). + * + * Warning: + * When using future callbacks, inside actors you need to carefully avoid closing over + * the containing actor’s object, i.e. do not call methods or access mutable state + * on the enclosing actor from within the callback. This would break the actor + * encapsulation and may introduce synchronization bugs and race conditions because + * the callback will be scheduled concurrently to the enclosing actor. Unfortunately + * there is not yet a way to detect these illegal accesses at compile time. + * + * Recommended usage: + * + * {{{ + * val f = worker ? request + * flow { + * EnrichedRequest(request, f()) + * } pipeTo nextActor + * }}} + * + * [see the [[akka.dispatch.Future]] companion object for a description of `flow`] + */ + def ?(message: Any)(implicit timeout: Timeout): Future[Any] = akka.pattern.ask(actorRef, message)(timeout) + + @deprecated("use ?(msg)(timeout), this method has dangerous ambiguity", "2.0-migration") + def ?(message: Any, timeout: Timeout)(i: Int = 0): Future[Any] = this.?(message)(timeout) +} \ No newline at end of file diff --git a/akka-actor-migration/src/main/scala/akka/migration/package.scala b/akka-actor-migration/src/main/scala/akka/migration/package.scala index 319fdd997e..4fd8d5eeea 100644 --- a/akka-actor-migration/src/main/scala/akka/migration/package.scala +++ b/akka-actor-migration/src/main/scala/akka/migration/package.scala @@ -31,4 +31,7 @@ package object migration { def stop(): Unit = GlobalActorSystem.stop(actorRef) } + implicit def ask(actorRef: ActorRef) = new akka.migration.AskableActorRef(actorRef) + def ask(actorRef: ActorRef, message: Any)(implicit timeout: Timeout = null): Future[Any] = akka.pattern.ask(actorRef, message)(timeout) + } \ No newline at end of file diff --git a/akka-actor/src/main/scala/akka/pattern/AskSupport.scala b/akka-actor/src/main/scala/akka/pattern/AskSupport.scala index ca07ea5052..57dec1debe 100644 --- a/akka-actor/src/main/scala/akka/pattern/AskSupport.scala +++ b/akka-actor/src/main/scala/akka/pattern/AskSupport.scala @@ -81,7 +81,7 @@ object AskSupport { * * [see the [[akka.dispatch.Future]] companion object for a description of `flow`] */ - def ?(message: Any)(implicit timeout: Timeout): Future[Any] = akka.pattern.ask(actorRef, message)(timeout) + def ?(message: Any)(implicit timeout: Timeout = null): Future[Any] = akka.pattern.ask(actorRef, message)(timeout) } /** 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 a3f874894d..33752b8ce7 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 @@ -205,6 +205,26 @@ Documentation: * :ref:`actors-scala` * :ref:`untyped-actors-java` +``ActorRef.?(msg, timeout)`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This method has a dangerous overlap with ``ActorRef.?(msg)(implicit timeout)`` +due to the fact that Scala allows to pass a :class:`Tuple` in place of the +message without requiring extra parentheses:: + + actor ? (1, "hallo") // will send a tuple + actor ? (1, Timeout()) // will send 1 with an explicit timeout + +To remove this ambiguity, the latter variant is removed in version 2.0. If you +were using it before, it will now send tuples where that is not desired. In +order to correct all places in the code where this happens, simply import +``akka.migration.ask`` instead of ``akka.pattern.ask`` to obtain a variant +which will give deprecation warnings where the old method signature is used:: + + import akka.migration.ask + + actor ? (1, Timeout(2 seconds)) // will give deprecation warning + ActorPool ^^^^^^^^^ From 71d58c5338d50d1d798f545fcf98264b4db472c8 Mon Sep 17 00:00:00 2001 From: Roland Date: Mon, 23 Jan 2012 11:58:27 +0100 Subject: [PATCH 15/18] improve migration guide & helpers, plus some docs --- .../src/main/scala/akka/actor/OldActor.scala | 4 +- .../main/scala/akka/pattern/Patterns.scala | 11 ++- .../project/migration-guide-1.3.x-2.0.x.rst | 68 +++++++++++++++---- 3 files changed, 64 insertions(+), 19 deletions(-) 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` From 3a30f915c3bfb626c8d506a85e96b3957db1944a Mon Sep 17 00:00:00 2001 From: Roland Date: Mon, 23 Jan 2012 15:59:18 +0100 Subject: [PATCH 16/18] remove use of `akka.actor.timeout` property for `ask` --- .../akka/migration/AskableActorRef.scala | 2 +- .../src/test/scala/akka/pattern/AskSpec.scala | 3 +- .../main/scala/akka/pattern/AskSupport.scala | 4 +-- .../main/scala/akka/pattern/Patterns.scala | 33 ------------------- .../src/main/scala/akka/pattern/package.scala | 17 +++++----- .../docs/actor/UntypedActorDocTestBase.java | 4 +-- .../project/migration-guide-1.3.x-2.0.x.rst | 15 ++++++--- akka-docs/scala/actors.rst | 3 -- 8 files changed, 25 insertions(+), 56 deletions(-) diff --git a/akka-actor-migration/src/main/scala/akka/migration/AskableActorRef.scala b/akka-actor-migration/src/main/scala/akka/migration/AskableActorRef.scala index caf8921812..fc4f28cd8b 100644 --- a/akka-actor-migration/src/main/scala/akka/migration/AskableActorRef.scala +++ b/akka-actor-migration/src/main/scala/akka/migration/AskableActorRef.scala @@ -37,7 +37,7 @@ class AskableActorRef(val actorRef: ActorRef) { * * [see the [[akka.dispatch.Future]] companion object for a description of `flow`] */ - def ask(message: Any)(implicit timeout: Timeout = null): Future[Any] = akka.pattern.ask(actorRef, message)(timeout) + def ask(message: Any)(implicit timeout: Timeout): Future[Any] = akka.pattern.ask(actorRef, message)(timeout) /** * Sends a message asynchronously and returns a [[akka.dispatch.Future]] diff --git a/akka-actor-tests/src/test/scala/akka/pattern/AskSpec.scala b/akka-actor-tests/src/test/scala/akka/pattern/AskSpec.scala index 44cdd91eba..ecb9690594 100644 --- a/akka-actor-tests/src/test/scala/akka/pattern/AskSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/pattern/AskSpec.scala @@ -4,6 +4,7 @@ package akka.pattern import akka.testkit.AkkaSpec +import akka.util.duration._ class AskSpec extends AkkaSpec { @@ -11,7 +12,7 @@ class AskSpec extends AkkaSpec { "return broken promises on DeadLetters" in { val dead = system.actorFor("/system/deadLetters") - val f = dead ask 42 + val f = dead.ask(42)(1 second) f.isCompleted must be(true) f.value.get match { case Left(_: AskTimeoutException) ⇒ diff --git a/akka-actor/src/main/scala/akka/pattern/AskSupport.scala b/akka-actor/src/main/scala/akka/pattern/AskSupport.scala index 57dec1debe..492bb46ed8 100644 --- a/akka-actor/src/main/scala/akka/pattern/AskSupport.scala +++ b/akka-actor/src/main/scala/akka/pattern/AskSupport.scala @@ -51,7 +51,7 @@ object AskSupport { * * [see the [[akka.dispatch.Future]] companion object for a description of `flow`] */ - def ask(message: Any)(implicit timeout: Timeout = null): Future[Any] = akka.pattern.ask(actorRef, message)(timeout) + def ask(message: Any)(implicit timeout: Timeout): Future[Any] = akka.pattern.ask(actorRef, message)(timeout) /** * Sends a message asynchronously and returns a [[akka.dispatch.Future]] @@ -81,7 +81,7 @@ object AskSupport { * * [see the [[akka.dispatch.Future]] companion object for a description of `flow`] */ - def ?(message: Any)(implicit timeout: Timeout = null): Future[Any] = akka.pattern.ask(actorRef, message)(timeout) + def ?(message: Any)(implicit timeout: Timeout): Future[Any] = akka.pattern.ask(actorRef, message)(timeout) } /** diff --git a/akka-actor/src/main/scala/akka/pattern/Patterns.scala b/akka-actor/src/main/scala/akka/pattern/Patterns.scala index b1498ee2d0..8c52f096f1 100644 --- a/akka-actor/src/main/scala/akka/pattern/Patterns.scala +++ b/akka-actor/src/main/scala/akka/pattern/Patterns.scala @@ -9,39 +9,6 @@ object Patterns { import akka.pattern.{ ask ⇒ scalaAsk } import akka.util.{ Timeout, Duration } - /** - * Java API for `akka.pattern.ask`: - * Sends a message asynchronously and returns a [[akka.dispatch.Future]] - * holding the eventual reply message; this means that the target actor - * needs to send the result to the `sender` reference provided. The Future - * will be completed with an [[akka.actor.AskTimeoutException]] after the - * given timeout has expired; this is independent from any timeout applied - * while awaiting a result for this future (i.e. in - * `Await.result(..., timeout)`). - * - * This variant will use the `akka.actor.timeout` from the configuration. - * - * Warning: - * When using future callbacks, inside actors you need to carefully avoid closing over - * the containing actor’s object, i.e. do not call methods or access mutable state - * on the enclosing actor from within the callback. This would break the actor - * encapsulation and may introduce synchronization bugs and race conditions because - * the callback will be scheduled concurrently to the enclosing actor. Unfortunately - * there is not yet a way to detect these illegal accesses at compile time. - * - * Recommended usage: - * - * {{{ - * final Future f = Patterns.ask(worker, request, timeout); - * f.onSuccess(new Procedure() { - * public void apply(Object o) { - * nextActor.tell(new EnrichedResult(request, o)); - * } - * }); - * }}} - */ - def ask(actor: ActorRef, message: Any): Future[AnyRef] = scalaAsk(actor, message).asInstanceOf[Future[AnyRef]] - /** * Java API for `akka.pattern.ask`: * Sends a message asynchronously and returns a [[akka.dispatch.Future]] diff --git a/akka-actor/src/main/scala/akka/pattern/package.scala b/akka-actor/src/main/scala/akka/pattern/package.scala index 4abb7c41d7..2689b72548 100644 --- a/akka-actor/src/main/scala/akka/pattern/package.scala +++ b/akka-actor/src/main/scala/akka/pattern/package.scala @@ -87,20 +87,19 @@ package object pattern { * * [see [[akka.dispatch.Future]] for a description of `flow`] */ - def ask(actorRef: ActorRef, message: Any)(implicit timeout: Timeout = null): Future[Any] = actorRef match { + def ask(actorRef: ActorRef, message: Any)(implicit timeout: Timeout): Future[Any] = actorRef match { case ref: InternalActorRef if ref.isTerminated ⇒ actorRef.tell(message) Promise.failed(new AskTimeoutException("sending to terminated ref breaks promises"))(ref.provider.dispatcher) case ref: InternalActorRef ⇒ val provider = ref.provider - (if (timeout == null) provider.settings.ActorTimeout else timeout) match { - case t if t.duration.length <= 0 ⇒ - actorRef.tell(message) - Promise.failed(new AskTimeoutException("not asking with negative timeout"))(provider.dispatcher) - case t ⇒ - val a = AskSupport.createAsker(provider, t) - actorRef.tell(message, a) - a.result + if (timeout.duration.length <= 0) { + actorRef.tell(message) + Promise.failed(new AskTimeoutException("not asking with negative timeout"))(provider.dispatcher) + } else { + val a = AskSupport.createAsker(provider, timeout) + actorRef.tell(message, a) + a.result } case _ ⇒ throw new IllegalArgumentException("incompatible ActorRef " + actorRef) } diff --git a/akka-docs/java/code/akka/docs/actor/UntypedActorDocTestBase.java b/akka-docs/java/code/akka/docs/actor/UntypedActorDocTestBase.java index eb8245ee57..a72c828862 100644 --- a/akka-docs/java/code/akka/docs/actor/UntypedActorDocTestBase.java +++ b/akka-docs/java/code/akka/docs/actor/UntypedActorDocTestBase.java @@ -231,8 +231,8 @@ public class UntypedActorDocTestBase { final Timeout t = new Timeout(Duration.create(5, TimeUnit.SECONDS)); final ArrayList> futures = new ArrayList>(); - futures.add(ask(actorA, "request")); // using `akka.actor.timeout` from config - futures.add(ask(actorB, "reqeest", t)); // using explicit timeout from above + futures.add(ask(actorA, "request", 1000)); // using 1000ms timeout + futures.add(ask(actorB, "reqeest", t)); // using timeout from above final Future> aggregate = Futures.sequence(futures, system.dispatcher()); 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 273d44c1d1..4dd9b8cc39 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 @@ -207,6 +207,9 @@ 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. +Since there is no good library default value for the ask-timeout, specification +of a timeout is required for all usages as shown below. + 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, @@ -221,15 +224,17 @@ v2.0 (Scala):: import akka.pattern.ask - actorRef ? message - ask(actorRef, message) // will use `akka.actor.timeout` or implicit Timeout - ask(actorRef, message)(timeout) + implicit val timeout: Timeout = ... + actorRef ? message // uses implicit timeout + actorRef ask message // uses implicit timeout + actorRef.ask(message)(timeout) // uses explicit timeout + ask(actorRef, message) // uses implicit timeout + ask(actorRef, message)(timeout) // uses explicit timeout v2.0 (Java):: import akka.pattern.Patterns; - Patterns.ask(actorRef, message) // will use `akka.actor.timeout` Patterns.ask(actorRef, message, timeout) Documentation: @@ -358,7 +363,7 @@ v2.0:: import akka.event.Logging val log = Logging(context.system, this) // will include system name in message source - val log = Logging(system.eventStream, this) // will not include system name + val log = Logging(system.eventStream, getClass.getName) // will not include system name log.error(exception, message) log.warning(message) log.info(message) diff --git a/akka-docs/scala/actors.rst b/akka-docs/scala/actors.rst index da0ae5b91e..fe1b134b65 100644 --- a/akka-docs/scala/actors.rst +++ b/akka-docs/scala/actors.rst @@ -389,9 +389,6 @@ taken from one of the following locations in order of precedence: .. includecode:: code/akka/docs/actor/ActorDocSpec.scala#using-implicit-timeout -3. actor system’s default value from ``akka.actor.timeout`` setting for - :meth:`ask` methods - See :ref:`futures-scala` for more information on how to await or query a future. From 7c9b044e11ff0c4769a07ac79aa7cf7e6c00265b Mon Sep 17 00:00:00 2001 From: Roland Date: Mon, 23 Jan 2012 18:23:34 +0100 Subject: [PATCH 17/18] =?UTF-8?q?incorporate=20Viktor=E2=80=99s=20review?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../akka/migration/AskableActorRef.scala | 12 +++++++++--- .../src/main/scala/akka/actor/ActorRef.scala | 19 ++++++++++--------- .../scala/akka/actor/ActorRefProvider.scala | 4 ++-- .../src/main/scala/akka/actor/Locker.scala | 5 ++++- .../main/scala/akka/pattern/AskSupport.scala | 12 +++++++++--- 5 files changed, 34 insertions(+), 18 deletions(-) diff --git a/akka-actor-migration/src/main/scala/akka/migration/AskableActorRef.scala b/akka-actor-migration/src/main/scala/akka/migration/AskableActorRef.scala index fc4f28cd8b..942d8ae47a 100644 --- a/akka-actor-migration/src/main/scala/akka/migration/AskableActorRef.scala +++ b/akka-actor-migration/src/main/scala/akka/migration/AskableActorRef.scala @@ -7,7 +7,10 @@ import akka.actor.ActorRef import akka.dispatch.Future import akka.util.Timeout -class AskableActorRef(val actorRef: ActorRef) { +/** + * Implementation detail of the “ask” pattern enrichment of ActorRef + */ +private[akka] final class AskableActorRef(val actorRef: ActorRef) { /** * Sends a message asynchronously and returns a [[akka.dispatch.Future]] @@ -29,8 +32,8 @@ class AskableActorRef(val actorRef: ActorRef) { * Recommended usage: * * {{{ - * val f = worker.ask(request)(timeout) * flow { + * val f = worker.ask(request)(timeout) * EnrichedRequest(request, f()) * } pipeTo nextActor * }}} @@ -59,8 +62,8 @@ class AskableActorRef(val actorRef: ActorRef) { * Recommended usage: * * {{{ - * val f = worker ? request * flow { + * val f = worker ? request * EnrichedRequest(request, f()) * } pipeTo nextActor * }}} @@ -69,6 +72,9 @@ class AskableActorRef(val actorRef: ActorRef) { */ def ?(message: Any)(implicit timeout: Timeout): Future[Any] = akka.pattern.ask(actorRef, message)(timeout) + /** + * This method is just there to catch 2.0-unsupported usage and print deprecation warnings for it. + */ @deprecated("use ?(msg)(timeout), this method has dangerous ambiguity", "2.0-migration") def ?(message: Any, timeout: Timeout)(i: Int = 0): Future[Any] = this.?(message)(timeout) } \ No newline at end of file diff --git a/akka-actor/src/main/scala/akka/actor/ActorRef.scala b/akka-actor/src/main/scala/akka/actor/ActorRef.scala index 2ed816a8fb..5ccce6906c 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorRef.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorRef.scala @@ -355,7 +355,7 @@ case class SerializedActorRef(path: String) { /** * Trait for ActorRef implementations where all methods contain default stubs. */ -trait MinimalActorRef extends InternalActorRef with LocalRef { +private[akka] trait MinimalActorRef extends InternalActorRef with LocalRef { def getParent: InternalActorRef = Nobody @@ -381,7 +381,7 @@ trait MinimalActorRef extends InternalActorRef with LocalRef { protected def writeReplace(): AnyRef = SerializedActorRef(path.toString) } -object MinimalActorRef { +private[akka] object MinimalActorRef { def apply(_path: ActorPath, _provider: ActorRefProvider)(receive: PartialFunction[Any, Unit]): ActorRef = new MinimalActorRef { def path = _path def provider = _provider @@ -392,7 +392,7 @@ object MinimalActorRef { case class DeadLetter(message: Any, sender: ActorRef, recipient: ActorRef) -object DeadLetterActorRef { +private[akka] object DeadLetterActorRef { class SerializedDeadLetterActorRef extends Serializable { //TODO implement as Protobuf for performance? @throws(classOf[java.io.ObjectStreamException]) private def readResolve(): AnyRef = Serialization.currentSystem.value.deadLetters @@ -401,7 +401,7 @@ object DeadLetterActorRef { val serialized = new SerializedDeadLetterActorRef } -trait DeadLetterActorRefLike extends MinimalActorRef { +private[akka] trait DeadLetterActorRefLike extends MinimalActorRef { def eventStream: EventStream @@ -427,11 +427,9 @@ trait DeadLetterActorRefLike extends MinimalActorRef { case d: DeadLetter ⇒ eventStream.publish(d) case _ ⇒ eventStream.publish(DeadLetter(message, sender, this)) } - - // FIXME reimplement behavior of brokenPromise on ask } -class DeadLetterActorRef(val eventStream: EventStream) extends DeadLetterActorRefLike { +private[akka] class DeadLetterActorRef(val eventStream: EventStream) extends DeadLetterActorRefLike { @throws(classOf[java.io.ObjectStreamException]) override protected def writeReplace(): AnyRef = DeadLetterActorRef.serialized } @@ -440,7 +438,7 @@ class DeadLetterActorRef(val eventStream: EventStream) extends DeadLetterActorRe * This special dead letter reference has a name: it is that which is returned * by a local look-up which is unsuccessful. */ -class EmptyLocalActorRef( +private[akka] class EmptyLocalActorRef( val eventStream: EventStream, _provider: ActorRefProvider, _dispatcher: MessageDispatcher, @@ -454,7 +452,10 @@ class EmptyLocalActorRef( } } -class VirtualPathContainer( +/** + * Internal implementation detail used for paths like “/temp” + */ +private[akka] class VirtualPathContainer( val provider: ActorRefProvider, val path: ActorPath, override val getParent: InternalActorRef, diff --git a/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala b/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala index f186710e39..da85eda2bf 100755 --- a/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala @@ -74,12 +74,12 @@ trait ActorRefProvider { /** * Registers an actorRef at a path returned by tempPath(); do NOT pass in any other path. */ - def registerTempActor(actorRef: InternalActorRef, path: ActorPath) + def registerTempActor(actorRef: InternalActorRef, path: ActorPath): Unit /** * Unregister a temporary actor from the “/temp” path (i.e. obtained from tempPath()); do NOT pass in any other path. */ - def unregisterTempActor(path: ActorPath) + def unregisterTempActor(path: ActorPath): Unit /** * Actor factory with create-only semantics: will create an actor as diff --git a/akka-actor/src/main/scala/akka/actor/Locker.scala b/akka-actor/src/main/scala/akka/actor/Locker.scala index efe98ab907..9e34f02332 100644 --- a/akka-actor/src/main/scala/akka/actor/Locker.scala +++ b/akka-actor/src/main/scala/akka/actor/Locker.scala @@ -9,7 +9,10 @@ import akka.util.duration._ import java.util.concurrent.ConcurrentHashMap import akka.event.DeathWatch -class Locker( +/** + * Internal implementation detail for disposing of orphaned actors. + */ +private[akka] class Locker( scheduler: Scheduler, period: Duration, val provider: ActorRefProvider, diff --git a/akka-actor/src/main/scala/akka/pattern/AskSupport.scala b/akka-actor/src/main/scala/akka/pattern/AskSupport.scala index 492bb46ed8..b9869a5126 100644 --- a/akka-actor/src/main/scala/akka/pattern/AskSupport.scala +++ b/akka-actor/src/main/scala/akka/pattern/AskSupport.scala @@ -19,9 +19,15 @@ class AskTimeoutException(message: String, cause: Throwable) extends TimeoutExce def this(message: String) = this(message, null: Throwable) } +/** + * This object contains implementation details of the “ask” pattern. + */ object AskSupport { - final class AskableActorRef(val actorRef: ActorRef) { + /** + * Implementation detail of the “ask” pattern enrichment of ActorRef + */ + private[akka] final class AskableActorRef(val actorRef: ActorRef) { /** * Sends a message asynchronously and returns a [[akka.dispatch.Future]] @@ -43,8 +49,8 @@ object AskSupport { * Recommended usage: * * {{{ - * val f = worker.ask(request)(timeout) * flow { + * val f = worker.ask(request)(timeout) * EnrichedRequest(request, f()) * } pipeTo nextActor * }}} @@ -73,8 +79,8 @@ object AskSupport { * Recommended usage: * * {{{ - * val f = worker ? request * flow { + * val f = worker ? request * EnrichedRequest(request, f()) * } pipeTo nextActor * }}} From 9d7ed5eba16152d15269bf4f626260432359c0d4 Mon Sep 17 00:00:00 2001 From: Roland Date: Mon, 23 Jan 2012 18:25:43 +0100 Subject: [PATCH 18/18] update copyright headers --- akka-actor/src/main/java/com/typesafe/config/Config.java | 2 +- .../src/main/java/com/typesafe/config/ConfigException.java | 2 +- akka-actor/src/main/java/com/typesafe/config/ConfigFactory.java | 2 +- .../src/main/java/com/typesafe/config/ConfigIncludeContext.java | 2 +- .../src/main/java/com/typesafe/config/ConfigIncluder.java | 2 +- akka-actor/src/main/java/com/typesafe/config/ConfigList.java | 2 +- .../src/main/java/com/typesafe/config/ConfigMergeable.java | 2 +- akka-actor/src/main/java/com/typesafe/config/ConfigObject.java | 2 +- akka-actor/src/main/java/com/typesafe/config/ConfigOrigin.java | 2 +- .../src/main/java/com/typesafe/config/ConfigParseOptions.java | 2 +- .../src/main/java/com/typesafe/config/ConfigParseable.java | 2 +- .../src/main/java/com/typesafe/config/ConfigResolveOptions.java | 2 +- akka-actor/src/main/java/com/typesafe/config/ConfigSyntax.java | 2 +- akka-actor/src/main/java/com/typesafe/config/ConfigValue.java | 2 +- .../src/main/java/com/typesafe/config/ConfigValueFactory.java | 2 +- .../src/main/java/com/typesafe/config/ConfigValueType.java | 2 +- .../java/com/typesafe/config/impl/AbstractConfigObject.java | 2 +- .../main/java/com/typesafe/config/impl/AbstractConfigValue.java | 2 +- .../src/main/java/com/typesafe/config/impl/ConfigBoolean.java | 2 +- .../main/java/com/typesafe/config/impl/ConfigDelayedMerge.java | 2 +- .../java/com/typesafe/config/impl/ConfigDelayedMergeObject.java | 2 +- .../src/main/java/com/typesafe/config/impl/ConfigDouble.java | 2 +- .../src/main/java/com/typesafe/config/impl/ConfigImpl.java | 2 +- .../src/main/java/com/typesafe/config/impl/ConfigImplUtil.java | 2 +- .../src/main/java/com/typesafe/config/impl/ConfigInt.java | 2 +- .../src/main/java/com/typesafe/config/impl/ConfigLong.java | 2 +- .../src/main/java/com/typesafe/config/impl/ConfigNull.java | 2 +- .../src/main/java/com/typesafe/config/impl/ConfigNumber.java | 2 +- .../src/main/java/com/typesafe/config/impl/ConfigString.java | 2 +- .../main/java/com/typesafe/config/impl/ConfigSubstitution.java | 2 +- .../main/java/com/typesafe/config/impl/DefaultTransformer.java | 2 +- .../src/main/java/com/typesafe/config/impl/FromMapMode.java | 2 +- .../src/main/java/com/typesafe/config/impl/Parseable.java | 2 +- akka-actor/src/main/java/com/typesafe/config/impl/Parser.java | 2 +- akka-actor/src/main/java/com/typesafe/config/impl/Path.java | 2 +- .../src/main/java/com/typesafe/config/impl/PathBuilder.java | 2 +- .../main/java/com/typesafe/config/impl/PropertiesParser.java | 2 +- .../src/main/java/com/typesafe/config/impl/ResolveStatus.java | 2 +- .../src/main/java/com/typesafe/config/impl/SimpleConfig.java | 2 +- .../main/java/com/typesafe/config/impl/SimpleConfigList.java | 2 +- .../main/java/com/typesafe/config/impl/SimpleConfigObject.java | 2 +- .../main/java/com/typesafe/config/impl/SimpleConfigOrigin.java | 2 +- .../java/com/typesafe/config/impl/SubstitutionResolver.java | 2 +- akka-actor/src/main/java/com/typesafe/config/impl/Token.java | 2 +- .../src/main/java/com/typesafe/config/impl/TokenType.java | 2 +- .../src/main/java/com/typesafe/config/impl/Tokenizer.java | 2 +- akka-actor/src/main/java/com/typesafe/config/impl/Tokens.java | 2 +- .../src/main/java/com/typesafe/config/impl/Unmergeable.java | 2 +- akka-actor/src/main/scala/akka/pattern/AskSupport.scala | 2 +- akka-actor/src/main/scala/akka/pattern/Patterns.scala | 2 +- akka-actor/src/main/scala/akka/pattern/PipeToSupport.scala | 2 +- akka-actor/src/main/scala/akka/pattern/package.scala | 2 +- akka-remote/src/multi-jvm/scala/akka/remote/ZKClient.scala | 2 +- akka-sbt-plugin/src/main/scala/AkkaKernelPlugin.scala | 2 +- 54 files changed, 54 insertions(+), 54 deletions(-) diff --git a/akka-actor/src/main/java/com/typesafe/config/Config.java b/akka-actor/src/main/java/com/typesafe/config/Config.java index d3496c73ef..e820d1b369 100644 --- a/akka-actor/src/main/java/com/typesafe/config/Config.java +++ b/akka-actor/src/main/java/com/typesafe/config/Config.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config; diff --git a/akka-actor/src/main/java/com/typesafe/config/ConfigException.java b/akka-actor/src/main/java/com/typesafe/config/ConfigException.java index b8dcb8ca00..3c31d811c3 100644 --- a/akka-actor/src/main/java/com/typesafe/config/ConfigException.java +++ b/akka-actor/src/main/java/com/typesafe/config/ConfigException.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config; diff --git a/akka-actor/src/main/java/com/typesafe/config/ConfigFactory.java b/akka-actor/src/main/java/com/typesafe/config/ConfigFactory.java index df5e762a5c..bb3f0aa131 100644 --- a/akka-actor/src/main/java/com/typesafe/config/ConfigFactory.java +++ b/akka-actor/src/main/java/com/typesafe/config/ConfigFactory.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config; diff --git a/akka-actor/src/main/java/com/typesafe/config/ConfigIncludeContext.java b/akka-actor/src/main/java/com/typesafe/config/ConfigIncludeContext.java index 2be0abff34..ac3644a5af 100644 --- a/akka-actor/src/main/java/com/typesafe/config/ConfigIncludeContext.java +++ b/akka-actor/src/main/java/com/typesafe/config/ConfigIncludeContext.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config; diff --git a/akka-actor/src/main/java/com/typesafe/config/ConfigIncluder.java b/akka-actor/src/main/java/com/typesafe/config/ConfigIncluder.java index 1ac6f3383d..38e8e35a91 100644 --- a/akka-actor/src/main/java/com/typesafe/config/ConfigIncluder.java +++ b/akka-actor/src/main/java/com/typesafe/config/ConfigIncluder.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config; diff --git a/akka-actor/src/main/java/com/typesafe/config/ConfigList.java b/akka-actor/src/main/java/com/typesafe/config/ConfigList.java index 2024efe744..5c694a508e 100644 --- a/akka-actor/src/main/java/com/typesafe/config/ConfigList.java +++ b/akka-actor/src/main/java/com/typesafe/config/ConfigList.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config; diff --git a/akka-actor/src/main/java/com/typesafe/config/ConfigMergeable.java b/akka-actor/src/main/java/com/typesafe/config/ConfigMergeable.java index 1214db8c44..c760bf9d15 100644 --- a/akka-actor/src/main/java/com/typesafe/config/ConfigMergeable.java +++ b/akka-actor/src/main/java/com/typesafe/config/ConfigMergeable.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config; diff --git a/akka-actor/src/main/java/com/typesafe/config/ConfigObject.java b/akka-actor/src/main/java/com/typesafe/config/ConfigObject.java index bb4d14da89..16b9837f6d 100644 --- a/akka-actor/src/main/java/com/typesafe/config/ConfigObject.java +++ b/akka-actor/src/main/java/com/typesafe/config/ConfigObject.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config; diff --git a/akka-actor/src/main/java/com/typesafe/config/ConfigOrigin.java b/akka-actor/src/main/java/com/typesafe/config/ConfigOrigin.java index fbc1fe17c3..c34767fb2e 100644 --- a/akka-actor/src/main/java/com/typesafe/config/ConfigOrigin.java +++ b/akka-actor/src/main/java/com/typesafe/config/ConfigOrigin.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config; diff --git a/akka-actor/src/main/java/com/typesafe/config/ConfigParseOptions.java b/akka-actor/src/main/java/com/typesafe/config/ConfigParseOptions.java index f3765a5479..2d057e812f 100644 --- a/akka-actor/src/main/java/com/typesafe/config/ConfigParseOptions.java +++ b/akka-actor/src/main/java/com/typesafe/config/ConfigParseOptions.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config; diff --git a/akka-actor/src/main/java/com/typesafe/config/ConfigParseable.java b/akka-actor/src/main/java/com/typesafe/config/ConfigParseable.java index 1cc39614ca..8c19085513 100644 --- a/akka-actor/src/main/java/com/typesafe/config/ConfigParseable.java +++ b/akka-actor/src/main/java/com/typesafe/config/ConfigParseable.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config; diff --git a/akka-actor/src/main/java/com/typesafe/config/ConfigResolveOptions.java b/akka-actor/src/main/java/com/typesafe/config/ConfigResolveOptions.java index 3adb589f1d..d82a6be71a 100644 --- a/akka-actor/src/main/java/com/typesafe/config/ConfigResolveOptions.java +++ b/akka-actor/src/main/java/com/typesafe/config/ConfigResolveOptions.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config; diff --git a/akka-actor/src/main/java/com/typesafe/config/ConfigSyntax.java b/akka-actor/src/main/java/com/typesafe/config/ConfigSyntax.java index 7626a92e6d..54529fad0b 100644 --- a/akka-actor/src/main/java/com/typesafe/config/ConfigSyntax.java +++ b/akka-actor/src/main/java/com/typesafe/config/ConfigSyntax.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config; diff --git a/akka-actor/src/main/java/com/typesafe/config/ConfigValue.java b/akka-actor/src/main/java/com/typesafe/config/ConfigValue.java index b636c6f4cd..1f389be08f 100644 --- a/akka-actor/src/main/java/com/typesafe/config/ConfigValue.java +++ b/akka-actor/src/main/java/com/typesafe/config/ConfigValue.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config; diff --git a/akka-actor/src/main/java/com/typesafe/config/ConfigValueFactory.java b/akka-actor/src/main/java/com/typesafe/config/ConfigValueFactory.java index 14c2bff8f7..babace186e 100644 --- a/akka-actor/src/main/java/com/typesafe/config/ConfigValueFactory.java +++ b/akka-actor/src/main/java/com/typesafe/config/ConfigValueFactory.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config; diff --git a/akka-actor/src/main/java/com/typesafe/config/ConfigValueType.java b/akka-actor/src/main/java/com/typesafe/config/ConfigValueType.java index 981cb6d189..a15774d3ce 100644 --- a/akka-actor/src/main/java/com/typesafe/config/ConfigValueType.java +++ b/akka-actor/src/main/java/com/typesafe/config/ConfigValueType.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config; diff --git a/akka-actor/src/main/java/com/typesafe/config/impl/AbstractConfigObject.java b/akka-actor/src/main/java/com/typesafe/config/impl/AbstractConfigObject.java index a21ccd81f7..1eb31c6397 100644 --- a/akka-actor/src/main/java/com/typesafe/config/impl/AbstractConfigObject.java +++ b/akka-actor/src/main/java/com/typesafe/config/impl/AbstractConfigObject.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config.impl; diff --git a/akka-actor/src/main/java/com/typesafe/config/impl/AbstractConfigValue.java b/akka-actor/src/main/java/com/typesafe/config/impl/AbstractConfigValue.java index e51f4c6067..46063f410e 100644 --- a/akka-actor/src/main/java/com/typesafe/config/impl/AbstractConfigValue.java +++ b/akka-actor/src/main/java/com/typesafe/config/impl/AbstractConfigValue.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config.impl; diff --git a/akka-actor/src/main/java/com/typesafe/config/impl/ConfigBoolean.java b/akka-actor/src/main/java/com/typesafe/config/impl/ConfigBoolean.java index c926c0c942..a1a7677c78 100644 --- a/akka-actor/src/main/java/com/typesafe/config/impl/ConfigBoolean.java +++ b/akka-actor/src/main/java/com/typesafe/config/impl/ConfigBoolean.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config.impl; diff --git a/akka-actor/src/main/java/com/typesafe/config/impl/ConfigDelayedMerge.java b/akka-actor/src/main/java/com/typesafe/config/impl/ConfigDelayedMerge.java index 4cca7834bd..218aaca306 100644 --- a/akka-actor/src/main/java/com/typesafe/config/impl/ConfigDelayedMerge.java +++ b/akka-actor/src/main/java/com/typesafe/config/impl/ConfigDelayedMerge.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config.impl; diff --git a/akka-actor/src/main/java/com/typesafe/config/impl/ConfigDelayedMergeObject.java b/akka-actor/src/main/java/com/typesafe/config/impl/ConfigDelayedMergeObject.java index fe970d59c8..a9ff7bd3bf 100644 --- a/akka-actor/src/main/java/com/typesafe/config/impl/ConfigDelayedMergeObject.java +++ b/akka-actor/src/main/java/com/typesafe/config/impl/ConfigDelayedMergeObject.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config.impl; diff --git a/akka-actor/src/main/java/com/typesafe/config/impl/ConfigDouble.java b/akka-actor/src/main/java/com/typesafe/config/impl/ConfigDouble.java index c26d3cd6a9..65cfb5d966 100644 --- a/akka-actor/src/main/java/com/typesafe/config/impl/ConfigDouble.java +++ b/akka-actor/src/main/java/com/typesafe/config/impl/ConfigDouble.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config.impl; diff --git a/akka-actor/src/main/java/com/typesafe/config/impl/ConfigImpl.java b/akka-actor/src/main/java/com/typesafe/config/impl/ConfigImpl.java index 217f4385e9..73ddfdce5a 100644 --- a/akka-actor/src/main/java/com/typesafe/config/impl/ConfigImpl.java +++ b/akka-actor/src/main/java/com/typesafe/config/impl/ConfigImpl.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config.impl; diff --git a/akka-actor/src/main/java/com/typesafe/config/impl/ConfigImplUtil.java b/akka-actor/src/main/java/com/typesafe/config/impl/ConfigImplUtil.java index cbc0ecca09..4cbcff7aa3 100644 --- a/akka-actor/src/main/java/com/typesafe/config/impl/ConfigImplUtil.java +++ b/akka-actor/src/main/java/com/typesafe/config/impl/ConfigImplUtil.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config.impl; diff --git a/akka-actor/src/main/java/com/typesafe/config/impl/ConfigInt.java b/akka-actor/src/main/java/com/typesafe/config/impl/ConfigInt.java index 440b5ae8cf..d33bd21274 100644 --- a/akka-actor/src/main/java/com/typesafe/config/impl/ConfigInt.java +++ b/akka-actor/src/main/java/com/typesafe/config/impl/ConfigInt.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config.impl; diff --git a/akka-actor/src/main/java/com/typesafe/config/impl/ConfigLong.java b/akka-actor/src/main/java/com/typesafe/config/impl/ConfigLong.java index 6a72bc4cab..a2e2ab3228 100644 --- a/akka-actor/src/main/java/com/typesafe/config/impl/ConfigLong.java +++ b/akka-actor/src/main/java/com/typesafe/config/impl/ConfigLong.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config.impl; diff --git a/akka-actor/src/main/java/com/typesafe/config/impl/ConfigNull.java b/akka-actor/src/main/java/com/typesafe/config/impl/ConfigNull.java index fbdc21d7a5..91b8586674 100644 --- a/akka-actor/src/main/java/com/typesafe/config/impl/ConfigNull.java +++ b/akka-actor/src/main/java/com/typesafe/config/impl/ConfigNull.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config.impl; diff --git a/akka-actor/src/main/java/com/typesafe/config/impl/ConfigNumber.java b/akka-actor/src/main/java/com/typesafe/config/impl/ConfigNumber.java index 4a6bbd0b15..d2f4bb6ac4 100644 --- a/akka-actor/src/main/java/com/typesafe/config/impl/ConfigNumber.java +++ b/akka-actor/src/main/java/com/typesafe/config/impl/ConfigNumber.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config.impl; diff --git a/akka-actor/src/main/java/com/typesafe/config/impl/ConfigString.java b/akka-actor/src/main/java/com/typesafe/config/impl/ConfigString.java index 9b41e7f7ab..f5293c8fc7 100644 --- a/akka-actor/src/main/java/com/typesafe/config/impl/ConfigString.java +++ b/akka-actor/src/main/java/com/typesafe/config/impl/ConfigString.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config.impl; diff --git a/akka-actor/src/main/java/com/typesafe/config/impl/ConfigSubstitution.java b/akka-actor/src/main/java/com/typesafe/config/impl/ConfigSubstitution.java index f4441b81a5..23776e0011 100644 --- a/akka-actor/src/main/java/com/typesafe/config/impl/ConfigSubstitution.java +++ b/akka-actor/src/main/java/com/typesafe/config/impl/ConfigSubstitution.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config.impl; diff --git a/akka-actor/src/main/java/com/typesafe/config/impl/DefaultTransformer.java b/akka-actor/src/main/java/com/typesafe/config/impl/DefaultTransformer.java index 4391814acb..9a9bf5c6a9 100644 --- a/akka-actor/src/main/java/com/typesafe/config/impl/DefaultTransformer.java +++ b/akka-actor/src/main/java/com/typesafe/config/impl/DefaultTransformer.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config.impl; diff --git a/akka-actor/src/main/java/com/typesafe/config/impl/FromMapMode.java b/akka-actor/src/main/java/com/typesafe/config/impl/FromMapMode.java index ce6c3e3f0a..764a45664c 100644 --- a/akka-actor/src/main/java/com/typesafe/config/impl/FromMapMode.java +++ b/akka-actor/src/main/java/com/typesafe/config/impl/FromMapMode.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config.impl; diff --git a/akka-actor/src/main/java/com/typesafe/config/impl/Parseable.java b/akka-actor/src/main/java/com/typesafe/config/impl/Parseable.java index 62b8ee575a..4938603199 100644 --- a/akka-actor/src/main/java/com/typesafe/config/impl/Parseable.java +++ b/akka-actor/src/main/java/com/typesafe/config/impl/Parseable.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config.impl; diff --git a/akka-actor/src/main/java/com/typesafe/config/impl/Parser.java b/akka-actor/src/main/java/com/typesafe/config/impl/Parser.java index 5df0314fe6..1ba8535207 100644 --- a/akka-actor/src/main/java/com/typesafe/config/impl/Parser.java +++ b/akka-actor/src/main/java/com/typesafe/config/impl/Parser.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config.impl; diff --git a/akka-actor/src/main/java/com/typesafe/config/impl/Path.java b/akka-actor/src/main/java/com/typesafe/config/impl/Path.java index 193d930002..af6dfe8bf5 100644 --- a/akka-actor/src/main/java/com/typesafe/config/impl/Path.java +++ b/akka-actor/src/main/java/com/typesafe/config/impl/Path.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config.impl; diff --git a/akka-actor/src/main/java/com/typesafe/config/impl/PathBuilder.java b/akka-actor/src/main/java/com/typesafe/config/impl/PathBuilder.java index f46e78201e..ede6c66387 100644 --- a/akka-actor/src/main/java/com/typesafe/config/impl/PathBuilder.java +++ b/akka-actor/src/main/java/com/typesafe/config/impl/PathBuilder.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config.impl; diff --git a/akka-actor/src/main/java/com/typesafe/config/impl/PropertiesParser.java b/akka-actor/src/main/java/com/typesafe/config/impl/PropertiesParser.java index bd822e65e9..7c8c81fb07 100644 --- a/akka-actor/src/main/java/com/typesafe/config/impl/PropertiesParser.java +++ b/akka-actor/src/main/java/com/typesafe/config/impl/PropertiesParser.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config.impl; diff --git a/akka-actor/src/main/java/com/typesafe/config/impl/ResolveStatus.java b/akka-actor/src/main/java/com/typesafe/config/impl/ResolveStatus.java index 3f73eb5221..8deeaf520f 100644 --- a/akka-actor/src/main/java/com/typesafe/config/impl/ResolveStatus.java +++ b/akka-actor/src/main/java/com/typesafe/config/impl/ResolveStatus.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config.impl; diff --git a/akka-actor/src/main/java/com/typesafe/config/impl/SimpleConfig.java b/akka-actor/src/main/java/com/typesafe/config/impl/SimpleConfig.java index 17979ba6cc..a87b12316a 100644 --- a/akka-actor/src/main/java/com/typesafe/config/impl/SimpleConfig.java +++ b/akka-actor/src/main/java/com/typesafe/config/impl/SimpleConfig.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config.impl; diff --git a/akka-actor/src/main/java/com/typesafe/config/impl/SimpleConfigList.java b/akka-actor/src/main/java/com/typesafe/config/impl/SimpleConfigList.java index 1921826352..fa91ea6627 100644 --- a/akka-actor/src/main/java/com/typesafe/config/impl/SimpleConfigList.java +++ b/akka-actor/src/main/java/com/typesafe/config/impl/SimpleConfigList.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config.impl; diff --git a/akka-actor/src/main/java/com/typesafe/config/impl/SimpleConfigObject.java b/akka-actor/src/main/java/com/typesafe/config/impl/SimpleConfigObject.java index 953f26491f..c961ae6b34 100644 --- a/akka-actor/src/main/java/com/typesafe/config/impl/SimpleConfigObject.java +++ b/akka-actor/src/main/java/com/typesafe/config/impl/SimpleConfigObject.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config.impl; diff --git a/akka-actor/src/main/java/com/typesafe/config/impl/SimpleConfigOrigin.java b/akka-actor/src/main/java/com/typesafe/config/impl/SimpleConfigOrigin.java index f0a0dbd353..4f8859f050 100644 --- a/akka-actor/src/main/java/com/typesafe/config/impl/SimpleConfigOrigin.java +++ b/akka-actor/src/main/java/com/typesafe/config/impl/SimpleConfigOrigin.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config.impl; diff --git a/akka-actor/src/main/java/com/typesafe/config/impl/SubstitutionResolver.java b/akka-actor/src/main/java/com/typesafe/config/impl/SubstitutionResolver.java index 65a2b30900..7bb3bf3a61 100644 --- a/akka-actor/src/main/java/com/typesafe/config/impl/SubstitutionResolver.java +++ b/akka-actor/src/main/java/com/typesafe/config/impl/SubstitutionResolver.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config.impl; diff --git a/akka-actor/src/main/java/com/typesafe/config/impl/Token.java b/akka-actor/src/main/java/com/typesafe/config/impl/Token.java index afff3247d6..5f16d26e1d 100644 --- a/akka-actor/src/main/java/com/typesafe/config/impl/Token.java +++ b/akka-actor/src/main/java/com/typesafe/config/impl/Token.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config.impl; diff --git a/akka-actor/src/main/java/com/typesafe/config/impl/TokenType.java b/akka-actor/src/main/java/com/typesafe/config/impl/TokenType.java index fc617d9ee2..7853c09445 100644 --- a/akka-actor/src/main/java/com/typesafe/config/impl/TokenType.java +++ b/akka-actor/src/main/java/com/typesafe/config/impl/TokenType.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config.impl; diff --git a/akka-actor/src/main/java/com/typesafe/config/impl/Tokenizer.java b/akka-actor/src/main/java/com/typesafe/config/impl/Tokenizer.java index 280a028077..2fcee8e61a 100644 --- a/akka-actor/src/main/java/com/typesafe/config/impl/Tokenizer.java +++ b/akka-actor/src/main/java/com/typesafe/config/impl/Tokenizer.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config.impl; diff --git a/akka-actor/src/main/java/com/typesafe/config/impl/Tokens.java b/akka-actor/src/main/java/com/typesafe/config/impl/Tokens.java index d726d83d53..83bec62af3 100644 --- a/akka-actor/src/main/java/com/typesafe/config/impl/Tokens.java +++ b/akka-actor/src/main/java/com/typesafe/config/impl/Tokens.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config.impl; diff --git a/akka-actor/src/main/java/com/typesafe/config/impl/Unmergeable.java b/akka-actor/src/main/java/com/typesafe/config/impl/Unmergeable.java index e0d114e78d..0028f2e023 100644 --- a/akka-actor/src/main/java/com/typesafe/config/impl/Unmergeable.java +++ b/akka-actor/src/main/java/com/typesafe/config/impl/Unmergeable.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe Inc. + * Copyright (C) 2011-2012 Typesafe Inc. */ package com.typesafe.config.impl; diff --git a/akka-actor/src/main/scala/akka/pattern/AskSupport.scala b/akka-actor/src/main/scala/akka/pattern/AskSupport.scala index b9869a5126..3e637fc81d 100644 --- a/akka-actor/src/main/scala/akka/pattern/AskSupport.scala +++ b/akka-actor/src/main/scala/akka/pattern/AskSupport.scala @@ -1,5 +1,5 @@ /** - * Copyright (C) 2009-2011 Typesafe Inc. + * Copyright (C) 2009-2012 Typesafe Inc. */ package akka.pattern diff --git a/akka-actor/src/main/scala/akka/pattern/Patterns.scala b/akka-actor/src/main/scala/akka/pattern/Patterns.scala index 8c52f096f1..c3510d9b68 100644 --- a/akka-actor/src/main/scala/akka/pattern/Patterns.scala +++ b/akka-actor/src/main/scala/akka/pattern/Patterns.scala @@ -1,5 +1,5 @@ /** - * Copyright (C) 2009-2011 Typesafe Inc. + * Copyright (C) 2009-2012 Typesafe Inc. */ package akka.pattern diff --git a/akka-actor/src/main/scala/akka/pattern/PipeToSupport.scala b/akka-actor/src/main/scala/akka/pattern/PipeToSupport.scala index 6827946902..26f3b68e38 100644 --- a/akka-actor/src/main/scala/akka/pattern/PipeToSupport.scala +++ b/akka-actor/src/main/scala/akka/pattern/PipeToSupport.scala @@ -1,5 +1,5 @@ /** - * Copyright (C) 2009-2011 Typesafe Inc. + * Copyright (C) 2009-2012 Typesafe Inc. */ package akka.pattern diff --git a/akka-actor/src/main/scala/akka/pattern/package.scala b/akka-actor/src/main/scala/akka/pattern/package.scala index 2689b72548..ac8fcf2df2 100644 --- a/akka-actor/src/main/scala/akka/pattern/package.scala +++ b/akka-actor/src/main/scala/akka/pattern/package.scala @@ -1,5 +1,5 @@ /** - * Copyright (C) 2009-2011 Typesafe Inc. + * Copyright (C) 2009-2012 Typesafe Inc. */ package akka diff --git a/akka-remote/src/multi-jvm/scala/akka/remote/ZKClient.scala b/akka-remote/src/multi-jvm/scala/akka/remote/ZKClient.scala index 96bccb13fa..156c955566 100755 --- a/akka-remote/src/multi-jvm/scala/akka/remote/ZKClient.scala +++ b/akka-remote/src/multi-jvm/scala/akka/remote/ZKClient.scala @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe + * Copyright (C) 2011-2012 Typesafe */ package akka.remote diff --git a/akka-sbt-plugin/src/main/scala/AkkaKernelPlugin.scala b/akka-sbt-plugin/src/main/scala/AkkaKernelPlugin.scala index ad6d2f13ea..5031723f44 100644 --- a/akka-sbt-plugin/src/main/scala/AkkaKernelPlugin.scala +++ b/akka-sbt-plugin/src/main/scala/AkkaKernelPlugin.scala @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Typesafe + * Copyright (C) 2011-2012 Typesafe */ package akka.sbt