Scala 使用Future进行并发搜索和结果返回
我正在创建一个服务,它运行一个单词列表,并为每个单词检查数据库中是否有相关的操作(执行) 我试图同时使用Futures来实现这一点,但我不确定我是否使用了最好的方法 ```Scala 使用Future进行并发搜索和结果返回,scala,Scala,我正在创建一个服务,它运行一个单词列表,并为每个单词检查数据库中是否有相关的操作(执行) 我试图同时使用Futures来实现这一点,但我不确定我是否使用了最好的方法 ``` class CommandDiscoveryService(commandsDAO:commandsDAO,text:String){ val words=text.split(\\s+) var results=newlistbuffer[选项[执行]]() //临时处理数据库上的并发搜索 //TODO将所有命令加载到内存
class CommandDiscoveryService(commandsDAO:commandsDAO,text:String){
val words=text.split(\\s+)
var results=newlistbuffer[选项[执行]]()
//临时处理数据库上的并发搜索
//TODO将所有命令加载到内存并检查列表??memcache或其他一些缓存服务
如果(字数、大小){
如果(分辨率>0){
Logger.debug(“RES SIZE:+RES.SIZE”)
res.map{ex=>results+=Some(ex)}
}
}
}
}
}
def getExecution():选项[执行]={
如果(results.size>1){
debug(“ERROR\u TOMANYEXECS:发现多个执行”+results.head)
结果:foreach{
execs=>Logger.debug(“对anyexecs的错误:+execs”)
}
没有一个
}否则{
如果(results.size==0){
debug(“在RES中找不到任何内容”)
没有一个
}否则{
Logger.debug(“找到的RES”+results.head)
结果:头
}
}
}
}
```
当我调用getExecution时,我需要已经获得搜索完成的值。我不确定锁定此结果变量是否是一个解决方案,因为等待未来[Seq[Execution]]已经不推荐了
PS:我正在使用playframework 2.6.x和Slick来运行它。您的
结果
ListBuffer
只填充了一些[执行]
,永远不要使用None
,因此在那里使用选项没有意义。我建议使用不可变集合并重新定义findExecution
方法以返回未来[列表[执行]]
:
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
现在返回所有单词或名称的执行
的单个未来
,但没有任何执行
的单词除外
当我调用getExecution时,我需要已经获得搜索完成的值
更好的方法是让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)
}
}
}
上述方法避免了阻塞wait
调用,并适合异步播放和灵活的API。您的结果
列表缓冲区
仅填充了部分[执行]
,永远不要使用None
,因此在那里使用选项没有意义。我建议使用不可变集合并重新定义findExecution
方法以返回未来[列表[执行]]
:
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
现在返回所有单词或名称的执行
的单个未来
,但没有任何执行
的单词除外
当我调用getExecution时,我需要已经获得搜索完成的值
更好的方法是让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
调用,并适合异步播放和灵活的API。No.Await.result是阻塞的,因此不好,但我需要等待结果。No.Await.result是阻塞的,因此不好,但我需要等待结果。我必须将序列(过滤)更改为序列(filtered.toList)进行编译,但这似乎可以正常工作。java.sql.SQLException:在连接获取过程中被中断…我收到了这个错误,我可以假设未来没有等待完成吗?我必须将序列(filtered)更改为序列(filtered.toList)对于它的编译,其他的似乎是可行的。java.sql.SQLException:在连接获取过程中被中断…我得到了这个错误,我可以假设未来没有等待完成吗?