Question

I am looking for a light weight library that allows me, instead of writing:

val future1 = process1()
future1.onSuccess { process2() }

the following:

val future1 = process1()
future1.await()
process2()

without blocking the thread (so not: Await.result(future1)) That is, I am imagining a continuations based library which transforms the latter into the former.

Was it helpful?

Solution

The only such library I know currently is Akka DataFlow: http://doc.akka.io/docs/akka/snapshot/scala/dataflow.html

Looking at the project definition (https://github.com/akka/akka/blob/master/project/AkkaBuild.scala), it seems that akka-dataflow does not have much dependencies, so it should be pretty lightweight.

UPDATE: Here's an example use, taken from akka-dataflow's documentation:

flow {
  val f1 = flow { "Hello" }
  val f2 = flow { "world!" }
  f1() + " " + f2()
} onComplete println

Which clearly illustrate that you can write your code in a procedural way (even though under the hood this really is transformed into a map/flatMap chain).

As another smple alternative, have you considered just using for continuations? They are bit more verbose to use, but the general benefit is the same: writing your code procedurally instead of cluttering it with explicit cps-style. By example, the above example directly translates to the following pure scala code:

{for {
  f1 <- future( "Hello" );
  f2 <- future( "world!" )
} yield f1 + " " + f2
} onComplete println

Which is not that different. And you won't find a more lightweight library than no library (though I admit that I still prefer akka-dataflow in terms of conciseness, but only by a slight margin).

OTHER TIPS

Taka a look at Akka Dataflow Concurrency. Looks like exactly what you want!

Example (see the documentation):

flow {
  val f1 = flow { "Hello" }
  val f2 = flow { "world!" }
  f1() + " " + f2()
} onComplete println

Akka Dataflow uses Scala's Delimited Continuations to automatically and behind the scenes generate the continuations for you.

This question was asked one year ago. Today, a more promising alternative than Akka Dataflow is scala-async, available at https://github.com/scala/async.

Akka Dataflow relies on the continuation plugin which is not actively maintained and is on the path to deprecation.

On the other hand, scala-async does not try to be a general purpose cps solution, but only tackles the writing of asynchronous code (which I believe happens to be the most common use case of the cps plugin). In other words it directly implements the equivalent of Akka's flow method (with the help of macros), and as such has a narrower (and better defined) scope than the cps plugin, which I think is key in allowing it be a better implementation overall.

Here is an example taken from the readme page:

val future = async {
  val f1 = async { ...; true }
  val f2 = async { ...; 42 }
  if (await(f1)) await(f2) else 0
}

There is one more dataflow concurrency implementation in Scala, that you might want to checkout, ScalaFLow. The github repo contains the thesis PDF as well, describing the work in very good detail.

Kai gives a demo in this forum thread:

Quote:

"A minimal demo (yes, looks like Futures):

val v = new Variable[Int]
flow { println( v() ) // suspends without blocking }
flow { v := 42 // resumes above flow }

"

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top