首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >未来在并行搜索和结果返回中的应用

未来在并行搜索和结果返回中的应用
EN

Stack Overflow用户
提问于 2017-07-29 23:10:27
回答 1查看 71关注 0票数 0

我正在创建一个服务,它遍历一个单词列表,并对每个单词检查数据库中是否有相关的操作(执行)。

我试图同时使用Futures.com来做这件事,我不确定我是否在使用最好的方法。

代码语言:javascript
复制
```javascript

类CommandDiscoveryService (commandsDAO: CommandsDAO,text: String) {

val words = text.split("\s+")

var结果=新的ListBufferOption[Execution]

//临时处理数据库上的并发搜索

// TODO将所有命令加载到内存中并检查列表??memcache或其他缓存服务

if (words.size <= 6) {

代码语言:javascript
复制
Logger.debug("Searching for executions with text " + text )
代码语言:javascript
复制
findExecution()

}

def findExecution() ={

代码语言:javascript
复制
val lb = new ListBuffer[Future[Seq[Execution]]]()
代码语言:javascript
复制
for (word <- words) {
代码语言:javascript
复制
  lb += commandsDAO.findExecutionByName(word)
代码语言:javascript
复制
}
代码语言:javascript
复制
lb.foreach(Await.result(_, 1 seconds))
代码语言:javascript
复制
import scala.concurrent.ExecutionContext.Implicits.global // FIXME LATER
代码语言:javascript
复制
val res = lb.map {
代码语言:javascript
复制
  ftr => ftr.map{
代码语言:javascript
复制
    res => {
代码语言:javascript
复制
      if (res.size > 0 ) {
代码语言:javascript
复制
        Logger.debug("RES SIZE:" + res.size)
代码语言:javascript
复制
        res.map{ ex => results += Some(ex) }
代码语言:javascript
复制
      }
代码语言:javascript
复制
    }
代码语言:javascript
复制
  }
代码语言:javascript
复制
}

}

def getExecution():OptionExecution ={

代码语言:javascript
复制
if (results.size > 1 ) {
代码语言:javascript
复制
  Logger.debug("ERROR_TOMANYEXECS: Found more than one execution " + results.head)
代码语言:javascript
复制
  results.foreach{
代码语言:javascript
复制
    execs => Logger.debug("ERROR_TOMANYEXECS: " + execs)
代码语言:javascript
复制
  }
代码语言:javascript
复制
  None
代码语言:javascript
复制
} else {
代码语言:javascript
复制
  if (results.size == 0 ) {
代码语言:javascript
复制
    Logger.debug("NOTHING FOUND IN RES")
代码语言:javascript
复制
    None
代码语言:javascript
复制
  } else {
代码语言:javascript
复制
    Logger.debug("FOUND RES " + results.head)
代码语言:javascript
复制
    results.head
代码语言:javascript
复制
  }
代码语言:javascript
复制
}

}

}

代码语言:javascript
复制

当我调用getExecution时,我需要已经获得搜索完成的值。我不确定对这个结果变量执行锁定是否是一个解决方案,Future[SeqExecution]上的等待已经没有恢复。

PS:我使用的是PlayFramework2.6.x和Slick来运行它。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-07-30 04:29:01

您的results ListBuffer只填充了Some[Execution],而没有使用None,因此在那里使用Option是没有意义的。我建议使用不可变集合,并重新定义findExecution方法以返回Future[List[Execution]]

代码语言:javascript
复制
val words = text.split("\\s+").toList

def findExecution: Future[List[Execution]] = {
  val executions = words.map(commandsDAO.findExecutionByName(_)) // List[Future[Seq[Execution]]]
  val filtered = executions.map(_.filter(_.nonEmpty)) // List[Future[Seq[Execution]]
  val flattened = Future.sequence(filtered).map(_.flatten) // Future[List[Execution]]
  flattened
}

findExecution现在返回所有单词或名称的所有Executions的单个Future,但没有任何Executions的单词除外。

当我调用getExecution时,我需要已经获得搜索完成的值

更好的方法是让getExecution也返回一个Future

代码语言:javascript
复制
def getExecution: Future[Option[Exception]] = {
  val executions = findExecution // Future[List[Execution]]
  executions.map { e =>
    if (e.size > 1) {
      // ...
      None
    } else if (e.isEmpty) {
      // ...
      None
    } else { // e.size is one
      // ...
      Some(e.head)
    }
  }
}

上述方法避免了阻塞Await调用,适合于异步播放和灵活的API。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45394892

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档