2017-07-29 68 views
0

我正在創建一個服務,該服務運行一個單詞列表,併爲每個單詞檢查數據庫中是否存在相關操作(執行)。使用未來進行併發搜索和結果返回

我正在嘗試使用Futures同時執行此操作,而且我不確定是否使用最佳方式。

```

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

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

    var results = new ListBuffer[Option[Execution]]() 

    // Temporarily handle with concurrent searchs on the database 
    // TODO Load all commands to memory and check the list ?? memcache or some other cache service 
    if (words.size <= 6) { 
    Logger.debug("Searching for executions with text " + text) 
    findExecution() 
    } 

    def findExecution() = { 
    val lb = new ListBuffer[Future[Seq[Execution]]]() 
    for (word <- words) { 
     lb += commandsDAO.findExecutionByName(word) 
    } 

    lb.foreach(Await.result(_, 1 seconds)) 

    import scala.concurrent.ExecutionContext.Implicits.global // FIXME LATER 
    val res = lb.map { 
     ftr => ftr.map{ 
     res => { 
      if (res.size > 0) { 
      Logger.debug("RES SIZE:" + res.size) 
      res.map{ ex => results += Some(ex) } 
      } 
     } 
     } 
    } 
    } 

    def getExecution(): Option[Execution] = { 
    if (results.size > 1) { 
     Logger.debug("ERROR_TOMANYEXECS: Found more than one execution " + results.head) 
     results.foreach{ 
     execs => Logger.debug("ERROR_TOMANYEXECS: " + execs) 
     } 

     None 
    } else { 
     if (results.size == 0) { 
     Logger.debug("NOTHING FOUND IN RES") 
     None 
     } else { 
     Logger.debug("FOUND RES " + results.head) 
     results.head 
     } 
    } 
    } 

} 

```

當我打電話getExecution我需要已經得到完成的搜索的價值。我不確定是否對這個結果變量進行鎖定將會成爲等待未來的解決方案[Seq [Execution]]已經不被推薦。 PS:我使用playframework 2.6.x和Slick來運行它。

+0

編號Await.result阻塞,因此它不好 –

+0

但我需要等待結果。 –

回答

2

resultsListBuffer僅填充了Some[Execution],從未有None,所以有在使用Option有沒有意義。我建議您用一成不變的收藏工作,並重新定義你的findExecution方法返回一個Future[List[Execution]]

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現在返回所有Execution S的所有單詞或名稱的單Future,除了不具有任何的話Execution s。

當我打電話getExecution我需要已經獲得完成

搜索的價值更好的方法是使​​回報Future還有:

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調用並適合異步Play和Slick API。

+0

我不得不將序列(過濾)更改爲序列(filtered.toList)以供它編譯,除此之外似乎可行。 –

+0

java.sql.SQLException:連接獲取期間中斷...我收到這個錯誤,我能否假設未來並沒有等待完成? –