使用Doobie可以并行运行多个查询吗?
我有以下(伪)查询:
def prepareForQuery(input: String): ConnectionIO[Unit] = ???
val gettAllResults: ConnectionIO[List[(String, BigDecimal)]] = ???
def program(input : String) : ConnectionIO[List[(String, BigDecimal)]] = for{
_ <- prepareForQuery(input)
r <- gettAllResults
} yield r
我尝试的是以下内容:
import doobie._
import doobie.implicits._
import cats.implicits._
val xa = Transactor.fromDataSource[IO](myDataSource)
val result = (program(i1),program(i2)).parMapN{case (a,b) => a ++ b}
val rs = result.transact(xa).unsafeRunSync
但是,ConnectionIO
没有找到NonEmptyParallel实例。
错误:(107,54)找不到参数p的隐含值: cats.NonEmptyParallel [doobie.ConnectionIO,F] val result = (程序(i1),程序(i2))。parMapN {case(a,b)=&gt; a ++ b}
我是否遗漏了一些明显或尝试无法完成的事情? 感谢
答案 0 :(得分:3)
您不能在ConnectionIO
monad中并行运行查询。但是,只要将它们转换为实际的运行时monad(只要它具有Parallel实例),就可以。
例如,使用cats-effect IO运行时monad:
def prepareForQuery(input: String): ConnectionIO[Unit] = ???
val gettAllResults: ConnectionIO[List[(String, BigDecimal)]] = ???
def program(input : String) : ConnectionIO[List[(String, BigDecimal)]] = for{
_ <- prepareForQuery(input)
r <- gettAllResults
} yield r
将您的ConnectionIO
变成IO
val program1IO: IO[List[(String, BigDecimal)]]] = program(i1).transact(xa)
val program2IO: IO[List[(String, BigDecimal)]]] = program(i2).transact(xa)
您现在有了一个可以并行执行操作的monad。
val result: IO[List[(String, BigDecimal)]]] =
(program1IO, program2IO).parMapN{case (a,b) => a ++ b}
要了解为什么ConnectionIO
不允许您并行执行操作,我只引用tpolecat:
您不能并行运行ConnectionIO。这是一种描述连接使用的语言,该连接是线性操作序列。
在IO中使用parMapN,是的,您可以同时运行两件事,因为它们运行在不同的连接上。
没有ConnectionIO的parMapN,因为它不(也不能)具有Parallel实例。