diff --git a/akka-actor/src/main/scala/akka/pattern/AskSupport.scala b/akka-actor/src/main/scala/akka/pattern/AskSupport.scala
index 2ebe7d3c70..afebca95c7 100644
--- a/akka-actor/src/main/scala/akka/pattern/AskSupport.scala
+++ b/akka-actor/src/main/scala/akka/pattern/AskSupport.scala
@@ -66,12 +66,11 @@ trait AskSupport {
*
* {{{
* val f = ask(worker, request)(timeout)
- * flow {
- * EnrichedRequest(request, f())
+ * f.map { response =>
+ * EnrichedMessage(response)
* } pipeTo nextActor
* }}}
*
- * See [[scala.concurrent.Future]] for a description of `flow`
*/
def ask(actorRef: ActorRef, message: Any)(implicit timeout: Timeout): Future[Any] = actorRef ? message
@@ -112,13 +111,12 @@ trait AskSupport {
* Recommended usage:
*
* {{{
- * val f = ask(selection, request)(timeout)
- * flow {
- * EnrichedRequest(request, f())
+ * val f = ask(worker, request)(timeout)
+ * f.map { response =>
+ * EnrichedMessage(response)
* } pipeTo nextActor
* }}}
*
- * See [[scala.concurrent.Future]] for a description of `flow`
*/
def ask(actorSelection: ActorSelection, message: Any)(implicit timeout: Timeout): Future[Any] = actorSelection ? message
}
diff --git a/akka-dataflow/src/main/scala/akka/dataflow/package.scala b/akka-dataflow/src/main/scala/akka/dataflow/package.scala
index 4537668f6b..b8587c4474 100644
--- a/akka-dataflow/src/main/scala/akka/dataflow/package.scala
+++ b/akka-dataflow/src/main/scala/akka/dataflow/package.scala
@@ -28,6 +28,7 @@ package object dataflow {
*
* The Delimited Continuations compiler plugin must be enabled in order to use this method.
*/
+ @deprecated("dataflow is deprecated, superseded by Scala Async", "2.3")
def flow[A](body: ⇒ A @cps[Future[Any]])(implicit executor: ExecutionContext): Future[A] = {
val p = Promise[A]
executor.execute(
@@ -43,6 +44,7 @@ package object dataflow {
p.future
}
+ @deprecated("dataflow is deprecated, superseded by Scala Async", "2.3")
implicit class DataflowPromise[T](val promise: Promise[T]) extends AnyVal {
/**
@@ -90,6 +92,7 @@ package object dataflow {
final def apply()(implicit ec: ExecutionContext): T @cps[Future[Any]] = shift(promise.future flatMap (_: T ⇒ Future[Any]))
}
+ @deprecated("dataflow is deprecated, superseded by Scala Async", "2.3")
implicit class DataflowFuture[T](val future: Future[T]) extends AnyVal {
/**
* For use only within a Future.flow block or another compatible Delimited Continuations reset block.
diff --git a/akka-docs/rst/intro/getting-started.rst b/akka-docs/rst/intro/getting-started.rst
index 46c8653dbb..6930d36936 100644
--- a/akka-docs/rst/intro/getting-started.rst
+++ b/akka-docs/rst/intro/getting-started.rst
@@ -34,9 +34,6 @@ Akka is very modular and consists of several JARs containing different features.
- ``akka-cluster`` – Cluster membership management, elastic routers.
-- ``akka-dataflow`` – add-on to SIP-14 futures supporting implicit
- continuation-passing style
-
- ``akka-file-mailbox`` – Akka durable mailbox (find more among community
projects)
diff --git a/akka-docs/rst/project/migration-guide-2.2.x-2.3.x.rst b/akka-docs/rst/project/migration-guide-2.2.x-2.3.x.rst
index 14f23ff079..1427d9f44a 100644
--- a/akka-docs/rst/project/migration-guide-2.2.x-2.3.x.rst
+++ b/akka-docs/rst/project/migration-guide-2.2.x-2.3.x.rst
@@ -99,6 +99,12 @@ Changed cluster expected-response-after configuration
Configuration property ``akka.cluster.failure-detector.heartbeat-request.expected-response-after``
has been renamed to ``akka.cluster.failure-detector.expected-response-after``.
+Dataflow is Deprecated
+======================
+
+Akka dataflow is superseded by `Scala Async `_.
+
+
Removed Deprecated Features
===========================
diff --git a/akka-docs/rst/scala/code/docs/dataflow/DataflowDocSpec.scala b/akka-docs/rst/scala/code/docs/dataflow/DataflowDocSpec.scala
deleted file mode 100644
index 69112a60e4..0000000000
--- a/akka-docs/rst/scala/code/docs/dataflow/DataflowDocSpec.scala
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- * Copyright (C) 2009-2013 Typesafe Inc.
- */
-package docs.dataflow
-
-import language.postfixOps
-
-import scala.concurrent.duration._
-import scala.concurrent.{ Await, Future, Promise }
-import org.scalatest.WordSpec
-import org.scalatest.matchers.MustMatchers
-import scala.util.{ Try, Failure, Success }
-
-class DataflowDocSpec extends WordSpec with MustMatchers {
-
- //#import-akka-dataflow
- import akka.dataflow._ //to get the flow method and implicit conversions
- //#import-akka-dataflow
-
- //#import-global-implicit
- import scala.concurrent.ExecutionContext.Implicits.global
- //#import-global-implicit
-
- "demonstrate flow using hello world" in {
- def println[T](any: Try[T]): Unit = any.get must be === "Hello world!"
- //#simplest-hello-world
- flow { "Hello world!" } onComplete println
- //#simplest-hello-world
-
- //#nested-hello-world-a
- flow {
- val f1 = flow { "Hello" }
- f1() + " world!"
- } onComplete println
- //#nested-hello-world-a
-
- //#nested-hello-world-b
- flow {
- val f1 = flow { "Hello" }
- val f2 = flow { "world!" }
- f1() + " " + f2()
- } onComplete println
- //#nested-hello-world-b
- }
-
- "demonstrate the use of dataflow variables" in {
- val result = Promise[Int]()
- def println(any: Try[Int]): Unit = result.complete(any)
- //#dataflow-variable-a
- val v1, v2 = Promise[Int]()
- flow {
- // v1 will become the value of v2 + 10 when v2 gets a value
- v1 << 10 + v2()
- v1() + v2()
- } onComplete println
- flow { v2 << 5 } // As you can see, no blocking above!
- //#dataflow-variable-a
- Await.result(result.future, 10.seconds) must be === 20
- }
-
- "demonstrate the difference between for and flow" in {
- val result = Promise[Int]()
- def println(any: Try[Int]): Unit = result.tryComplete(any)
- //#for-vs-flow
- val f1, f2 = Future { 1 }
-
- val usingFor = for { v1 <- f1; v2 <- f2 } yield v1 + v2
- val usingFlow = flow { f1() + f2() }
-
- usingFor onComplete println
- usingFlow onComplete println
- //#for-vs-flow
- Await.result(result.future, 10.seconds) must be === 2
- }
-
-}
diff --git a/akka-docs/rst/scala/dataflow.rst b/akka-docs/rst/scala/dataflow.rst
deleted file mode 100644
index 01ecd2a250..0000000000
--- a/akka-docs/rst/scala/dataflow.rst
+++ /dev/null
@@ -1,111 +0,0 @@
-Dataflow Concurrency
-============================
-
-Description
------------
-
-Akka implements `Oz-style dataflow concurrency `_
-by using a special API for :ref:`futures-scala` that enables a complementary way of writing synchronous-looking code that in reality is asynchronous.
-
-The benefit of Dataflow concurrency is that it is deterministic; that means that it will always behave the same.
-If you run it once and it yields output 5 then it will do that **every time**, run it 10 million times - same result.
-If it on the other hand deadlocks the first time you run it, then it will deadlock **every single time** you run it.
-Also, there is **no difference** between sequential code and concurrent code. These properties makes it very easy to reason about concurrency.
-The limitation is that the code needs to be side-effect free, i.e. deterministic.
-You can't use exceptions, time, random etc., but need to treat the part of your program that uses dataflow concurrency as a pure function with input and output.
-
-The best way to learn how to program with dataflow variables is to read the fantastic book `Concepts, Techniques, and Models of Computer Programming `_. By Peter Van Roy and Seif Haridi.
-
-Getting Started (SBT)
----------------------
-
-Scala's Delimited Continuations plugin is required to use the Dataflow API. To enable the plugin when using sbt, your project must inherit the ``AutoCompilerPlugins`` trait and contain a bit of configuration as is seen in this example:
-
-.. code-block:: scala
-
- autoCompilerPlugins := true,
- libraryDependencies <+= scalaVersion {
- v => compilerPlugin("org.scala-lang.plugins" % "continuations" % "@scalaVersion@")
- },
- scalacOptions += "-P:continuations:enable",
-
-
-You will also need to include a dependency on ``akka-dataflow``:
-
-.. code-block:: scala
-
- "com.typesafe.akka" %% "akka-dataflow" % "@version@" @crossString@
-
-Dataflow variables
-------------------
-
-A Dataflow variable can be read any number of times but only be written to once, which maps very well to the concept of Futures/Promises :ref:`futures-scala`.
-Conversion from ``Future`` and ``Promise`` to Dataflow Variables is implicit and is invisible to the user (after importing akka.dataflow._).
-
-The mapping from ``Promise`` and ``Future`` is as follows:
-
- - Futures are readable-many, using the ``apply`` method, inside ``flow`` blocks.
- - Promises are readable-many, just like Futures.
- - Promises are writable-once, using the ``<<`` operator, inside ``flow`` blocks.
- Writing to an already written Promise throws a ``java.lang.IllegalStateException``,
- this has the effect that races to write a promise will be deterministic,
- only one of the writers will succeed and the others will fail.
-
-The flow
---------
-
-The ``flow`` method acts as the delimiter of dataflow expressions (this also neatly aligns with the concept of delimited continuations),
-and flow-expressions compose. At this point you might wonder what the ``flow``-construct brings to the table that for-comprehensions don't,
-and that is the use of the CPS plugin that makes the *look like* it is synchronous, but in reality is asynchronous and non-blocking.
-The result of a call to ``flow`` is a Future with the resulting value of the flow.
-
-To be able to use the ``flow`` method, you need to import:
-
-.. includecode:: code/docs/dataflow/DataflowDocSpec.scala
- :include: import-akka-dataflow
-
-The ``flow`` method will, just like Futures and Promises, require an implicit ``ExecutionContext`` in scope.
-For the examples here we will use:
-
-.. includecode:: code/docs/dataflow/DataflowDocSpec.scala
- :include: import-global-implicit
-
-Using flow
-~~~~~~~~~~
-
-First off we have the obligatory "Hello world!":
-
-.. includecode:: code/docs/dataflow/DataflowDocSpec.scala
- :include: simplest-hello-world
-
-You can also refer to the results of other flows within flows:
-
-.. includecode:: code/docs/dataflow/DataflowDocSpec.scala
- :include: nested-hello-world-a
-
-… or:
-
-.. includecode:: code/docs/dataflow/DataflowDocSpec.scala
- :include: nested-hello-world-b
-
-Working with variables
-~~~~~~~~~~~~~~~~~~~~~~
-
-Inside the flow method you can use Promises as Dataflow variables:
-
-.. includecode:: code/docs/dataflow/DataflowDocSpec.scala
- :include: dataflow-variable-a
-
-Flow compared to for
---------------------
-
-Should I use Dataflow or for-comprehensions?
-
-.. includecode:: code/docs/dataflow/DataflowDocSpec.scala
- :include: for-vs-flow
-
-Conclusions:
-
- - Dataflow has a smaller code footprint and arguably is easier to reason about.
- - For-comprehensions are more general than Dataflow, and can operate on a wide array of types.
-
diff --git a/akka-docs/rst/scala/index-futures.rst b/akka-docs/rst/scala/index-futures.rst
index b8f350ad61..7768a39f41 100644
--- a/akka-docs/rst/scala/index-futures.rst
+++ b/akka-docs/rst/scala/index-futures.rst
@@ -5,7 +5,6 @@ Futures and Agents
:maxdepth: 2
futures
- dataflow
stm
agents
transactors
diff --git a/project/AkkaBuild.scala b/project/AkkaBuild.scala
index 14f75ab946..6bf84f7f66 100644
--- a/project/AkkaBuild.scala
+++ b/project/AkkaBuild.scala
@@ -619,7 +619,7 @@ object AkkaBuild extends Build {
id = "akka-docs",
base = file("akka-docs"),
dependencies = Seq(actor, testkit % "test->test", mailboxesCommon % "compile;test->test", channels,
- remote % "compile;test->test", cluster, slf4j, agent, dataflow, transactor, fileMailbox, zeroMQ, camel, osgi, osgiAries,
+ remote % "compile;test->test", cluster, slf4j, agent, transactor, fileMailbox, zeroMQ, camel, osgi, osgiAries,
persistence % "compile;test->test"),
settings = defaultSettings ++ docFormatSettings ++ site.settings ++ site.sphinxSupport() ++ site.publishSite ++ sphinxPreprocessing ++ cpsPlugin ++ Seq(
sourceDirectory in Sphinx <<= baseDirectory / "rst",