Is it possible to run multiple queries in parallel, using Doobie?
I have the following (pseudo)queries:
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
What I tried is the following:
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
However, no NonEmptyParallel instance is found for ConnectionIO
.
Error:(107, 54) could not find implicit value for parameter p: cats.NonEmptyParallel[doobie.ConnectionIO,F] val result = (program(i1),program(i2)).parMapN{case (a ,b) => a ++ b}
Am I missing something obvious or trying something that cannot be done? Thanks
You cannot run queries in the ConnectionIO
monad in parallel. But as soon as you turn them into your actual runtime monad (as long as it has a Parallel instance), you can.
For example, with the cats-effect IO runtime 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
Turn your ConnectionIO
into an IO
val program1IO: IO[List[(String, BigDecimal)]]] = program(i1).transact(xa)
val program2IO: IO[List[(String, BigDecimal)]]] = program(i2).transact(xa)
You now have a monad which can do things in parallel.
val result: IO[List[(String, BigDecimal)]]] =
(program1IO, program2IO).parMapN{case (a,b) => a ++ b}
To understand why ConnectionIO
doesn't allow you to do things in parallel, I'll just quote tpolecat:
You can't run ConnectionIO in parallel. It's a language describing the use of a connection which is a linear sequence of operations.
Using parMapN in IO, yes, you can run two things at the same time because they're running on different connections.
There is no parMapN with ConnectionIO because it does not (and cannot) have a Parallel instance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With