mdm*_*mdm 6 functional-programming scala scala-cats doobie
是否可以使用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
Run Code Online (Sandbox Code Playgroud)
我尝试了以下内容:
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
Run Code Online (Sandbox Code Playgroud)
但是,找不到的NonEmptyParallel实例ConnectionIO。
错误:(107,54)找不到参数p的隐式值:cats.NonEmptyParallel [doobie.ConnectionIO,F] val结果=(program(i1),program(i2))。parMapN {case(a,b)= > a ++ b}
我是否缺少明显的东西或尝试无法完成的事情?谢谢
您不能在ConnectionIOmonad 中并行运行查询。但是一旦你把它们变成你实际的运行时 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
Run Code Online (Sandbox Code Playgroud)
把你ConnectionIO变成一个IO
val program1IO: IO[List[(String, BigDecimal)]]] = program(i1).transact(xa)
val program2IO: IO[List[(String, BigDecimal)]]] = program(i2).transact(xa)
Run Code Online (Sandbox Code Playgroud)
你现在有一个可以并行处理的 monad。
val result: IO[List[(String, BigDecimal)]]] =
(program1IO, program2IO).parMapN{case (a,b) => a ++ b}
Run Code Online (Sandbox Code Playgroud)
要了解为什么ConnectionIO不允许您并行执行操作,我将引用 tpolecat:
您不能并行运行 ConnectionIO。它是一种描述连接使用的语言,连接是线性操作序列。
在 IO 中使用 parMapN,是的,您可以同时运行两件事,因为它们在不同的连接上运行。
ConnectionIO 没有 parMapN,因为它没有(也不能)有一个 Parallel 实例。