使用Scala 2.10期货获得良好数据流的CPS库

时间:2013-02-27 10:02:20

标签: scala future continuations

我正在寻找一个轻量级的库,它允许我,而不是写作:

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

以下内容:

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

没有阻塞线程(所以不是:Await.result(future1))也就是说,我想象一个基于continuation的库,它将后者转换为前者。

4 个答案:

答案 0 :(得分:4)

塔卡看看Akka Dataflow Concurrency。看起来就像你想要的那样!

示例(请参阅documentation):

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

Akka Dataflow自动使用Scala的Delimited Continuations,并在后台为您生成延续。

答案 1 :(得分:4)

我目前唯一知道的库 Akka DataFlow http://doc.akka.io/docs/akka/snapshot/scala/dataflow.html

查看项目定义(https://github.com/akka/akka/blob/master/project/AkkaBuild.scala),似乎akka-dataflow没有太多的依赖关系,所以它应该非常轻量级。

<强>更新 以下是一个示例用法,取自akka-dataflow的文档:

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

这清楚地说明了你可以用程序方式编写代码(尽管在引擎盖下这实际上已转换为map / flatMap链)。

作为另一个简单的替代,你考虑过只使用延续吗?它们使用起来有点冗长,但总的好处是相同的:从程序上编写代码而不是用显式的cps风格来混淆它。例如,上面的示例直接转换为以下纯scala代码:

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

哪个没有那么不同。而且你找不到比没有库更轻量级的库(虽然我承认我仍然更喜欢简洁性方面的akka​​-dataflow,但只是略有差距)。

答案 2 :(得分:4)

这个问题是在一年前提出来的。 今天,一个比Akka Dataflow更有前途的替代方案是 scala-async ,可在https://github.com/scala/async获得。

Akka Dataflow依赖于不会主动维护的延续插件,并且正在弃用。

另一方面, scala-async 不会尝试成为通用的cps解决方案,但只会解决异步代码的写入问题(我认为这是最常见的用例) cps插件)。 换句话说,它直接实现相当于Akka的flow方法(在宏的帮助下),因此具有比cps插件更窄(更好定义)的范围,我认为这是允许它的关键整体上更好的实施。

以下是自述页面的示例:

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

答案 3 :(得分:3)

Scala中还有一个数据流并发实现,您可能想要签出ScalaFLow。 github repo也包含论文PDF,非常详细地描述了这些工作。

Kai在this forum thread中提供了一个演示:

引用:

&#34;最小的演示(是的,看起来像期货):

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

&#34;