From c54e7b2a289e7030424ef0f612e2c5276f1c2cb1 Mon Sep 17 00:00:00 2001 From: Roland Date: Sun, 16 Oct 2011 18:33:35 +0200 Subject: [PATCH] add pimp for Future.pipeTo(Channel), closes #1235 cherry-picked from release-1.3 The ticket contains more methods around this issue, both on Actor and Future itself, but I think it is better to provide the basic primitive in a way which does not further couple Future and Actor. Will need to be revisited for 2.0. --- .../scala/akka/dataflow/Future2Actor.scala | 34 +++++++++++++++++++ .../src/main/scala/akka/actor/package.scala | 11 ++++++ 2 files changed, 45 insertions(+) create mode 100644 akka-actor-tests/src/test/scala/akka/dataflow/Future2Actor.scala diff --git a/akka-actor-tests/src/test/scala/akka/dataflow/Future2Actor.scala b/akka-actor-tests/src/test/scala/akka/dataflow/Future2Actor.scala new file mode 100644 index 0000000000..948af64106 --- /dev/null +++ b/akka-actor-tests/src/test/scala/akka/dataflow/Future2Actor.scala @@ -0,0 +1,34 @@ +/** + * Copyright (C) 2009-2011 Typesafe Inc. + */ +package akka.dataflow + +import akka.actor.{ Actor, Props } +import akka.dispatch.Future +import akka.actor.future2actor +import akka.util.duration._ +import akka.testkit.AkkaSpec + +class Future2ActorSpec extends AkkaSpec { + + "The Future2Actor bridge" must { + + "support convenient sending to multiple destinations" in { + Future(42) pipeTo testActor pipeTo testActor + expectMsgAllOf(1 second, 42, 42) + } + + "support reply via channel" in { + val actor = app.actorOf(Props(new Actor { + def receive = { + case "do" ⇒ Future(31) pipeTo context.channel + case "ex" ⇒ Future(throw new AssertionError) pipeTo context.channel + } + })) + (actor ? "do").as[Int] must be(Some(31)) + intercept[AssertionError] { + (actor ? "ex").get + } + } + } +} diff --git a/akka-actor/src/main/scala/akka/actor/package.scala b/akka-actor/src/main/scala/akka/actor/package.scala index 1b2e1514f9..a87ad02861 100644 --- a/akka-actor/src/main/scala/akka/actor/package.scala +++ b/akka-actor/src/main/scala/akka/actor/package.scala @@ -22,4 +22,15 @@ package object actor { n.substring(i + 1).replaceAll("\\$+", ".") } + implicit def future2actor[T](f: akka.dispatch.Future[T]) = new { + def pipeTo(channel: Channel[T]): this.type = { + if (f.isCompleted) { + f.value.get.fold(channel.sendException(_), channel.tryTell(_)) + } else { + f onComplete { _.value.get.fold(channel.sendException(_), channel.tryTell(_)) } + } + this + } + } + }