【发布时间】:2014-04-22 20:20:30
【问题描述】:
我们在 Scala Play Framework 应用程序中使用 Elasticsearch 0.90.7,其中“doSearch”方法的结尾如下所示:
def doSearch(...) = {
...
val actionRequessBuilder: ActionRequestBuilder // constructed earlier in the method
val executedFuture: ListenableActionFuture<Response> = actionRequestBuilder.execute
return executedFuture.actionGet
}
其中ListenableActionFuture扩展java.util.concurrent.Future,而ListenableActionFuture#actionGet与Future#get基本相同
当我们按顺序执行搜索时一切正常,但是当我们尝试并行执行多个搜索时:
val search1 = scala.concurrent.Future(doSearch(...))
val search2 = scala.concurrent.Future(doSearch(...))
return Await.result(search1, defaultDuration) -> Await.result(search2, defaultDuration))
我们有时(不到 1% 或 2% 的时间)在我们的 scala 期货上遇到意外超时,即使在 qa 期间使用极长的超时(5 秒,其中搜索总是在不到 200 毫秒内执行)。使用 scala 全局执行上下文以及使用 Play 默认执行上下文时也会发生这种情况。
由于将 java 未来包装在 scala 未来中,这里是否会发生某种意外的交互?我原以为在doSearch 结尾处对java 未来的actionGet 调用会阻止这两个未来相互干扰,但显然情况可能并非如此。
【问题讨论】:
-
可能做不到,但是如果您可以编写一个其他人可以运行的测试用例并重新创建问题,它可能有助于调试。
-
@JohnVint 我一直在尝试这样做,但不幸的是,低悬的果实 (
do while(i < 100) { i = i + 1; val f1 = Future(doSearch(...)); val f2 = Future(doSearch(...)); Await(f1, defaultDuration); Await(f2, defaultDuration)}) 并没有引发问题;我会继续玩这个,这样我就可以一直得到错误
标签: java multithreading scala concurrency scala-java-interop