2

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

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

以下:

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

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

4

4 回答 4

4

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

Akka Dataflow 依赖于 continuation 插件,该插件没有被积极维护并且正在弃用。

另一方面,scala-async并没有尝试成为通用的 cps 解决方案,而只是处理异步代码的编写(我相信这恰好是 cps 插件最常见的用例)。换句话说,它直接实现了 Akkaflow方法的等价物(在宏的帮助下),因此它的范围比 cps 插件更窄(并且定义更好),我认为这是让它成为一个更好的整体实现的关键。

这是从自述文件页面中获取的示例:

val future = async {
  val f1 = async { ...; true }
  val f2 = async { ...; 42 }
  if (await(f1)) await(f2) else 0
}
于 2014-02-21T13:57:20.853 回答
4

看看Akka Dataflow Concurrency。看起来正是你想要的!

示例(请参阅文档):

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

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

于 2013-02-27T10:22:40.667 回答
4

我目前知道的唯一这样的库是Akka DataFlowhttp ://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,但只是略微领先)。

于 2013-02-27T10:23:09.943 回答
3

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

Kai 在这个论坛帖子中给出了一个演示:

引用:

“一个最小的演示(是的,看起来像期货):

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

"

于 2013-09-27T14:01:43.527 回答