1

我使用 Spray API 来监听来自服务器的请求。一个特定的 scala 类中的计算最终会阻止 Spray 在整个应用程序中响应。这是对问题的轻微简化,但我可以提供更多信息。如果需要的话。

class SomeClass(implicit execc: ExecutionContext){
    implicit val x = ...
    val foo = Await.result(...someFunc(x))
}

我添加了这个导入,它解决了我的问题:

import scala.concurrent.ExecutionContext.Implicits.global

谁能解释这是如何或为什么起作用的?

==================================================== =

编辑:

OuterClass 实例化 SomeClass,但它本身从未使用 ExecutionContext 参数实例化。看来它可能默认使用全局执行上下文,这就是为什么它会阻塞呢?

class OuterClass(executor: ExecutionContext){
    val s = new someClass
}

val x = (new OuterClass).someFunction
4

1 回答 1

0

Spray 路由处理程序是一个单一的参与者,它接收来自 Spray IO/Spray-can/library 的 HTTP 请求并将它们传递给路由处理函数 - 本质上是一个自身没有并发的部分函数。因此,如果您的路由阻塞,Spray 也将阻塞并且请求将在路由处理程序参与者队列中排队。

有 3 种方法可以正确处理路由中的阻塞请求处理:为每个请求生成一个 actor、返回响应的 Future 或获取请求完成函数并在其他地方使用它来解除路由阻塞(如果有兴趣,请搜索更详细的解释)。

我无法确定在您的情况下使用了哪个执行上下文,但它在分配的线程和/或您的 Spray 路由处理程序和长时间运行的任务共享方面一定非常有限。这将导致它们都在同一个线程上运行。

如果您没有显式导入任何执行上下文,则必须通过常规范围的隐式解析找到它。您必须拥有一个,因为您将它作为构造函数参数。尝试检查你在范围内的隐含,看看它是哪一个。我很好奇自己是Spray提供的还是其他东西。

于 2015-05-27T02:28:44.680 回答