我使用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
答案 0 :(得分:0)
Spray route handler是一个单一的actor,它接收来自Spray IO / Spray-can / library的HTTP请求,并将它们传递给路由处理函数 - 本质上是一个没有并发性的部分函数。因此,如果您的路由阻塞,Spray也会阻塞,请求将在路由处理程序actor队列中排队。
有三种方法可以正确处理路径中的阻止请求处理:每个请求产生一个actor,返回响应的Future或获取请求完成功能,并在其他地方使用它来解锁路由(如果感兴趣,请搜索更详细的解释)。
我无法确定在您的情况下使用了哪个执行上下文,但它必须在分配的线程和/或您的Spray路由处理程序和长时间运行的任务共享方面非常有限。这将导致它们都在同一个线程上运行。
如果您没有明确导入任何执行上下文,则必须通过常规作用域的隐式解析找到它。你必须有一个,因为你有它作为构造函数参数。尝试检查范围中的含义,看看它是哪一个。我很好奇自己是Spray提供的还是别的东西。