Параллельный запуск запросов в 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

Я попробовал следующее:

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

Тем не менее, экземпляр NonEmptyParallel не найден для ConnectionIO,

Ошибка:(107, 54) не удалось найти неявное значение для параметра p: cats.NonEmptyParallel[doobie.ConnectionIO,F] val result = (program(i1),program(i2)). ParMapN{case (a,b) => a ++ b}

Я упускаю что-то очевидное или пытаюсь сделать что-то, что невозможно Спасибо

0 ответов

Вы не можете запускать запросы в ConnectionIOмонада параллельно. Но как только вы превратите их в вашу фактическую монаду времени выполнения (если у нее есть экземпляр Parallel), вы сможете.

Например, с монадой среды выполнения ввода-вывода cats-effect:

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)

Теперь у вас есть монада, которая может делать что-то параллельно.

val result: IO[List[(String, BigDecimal)]]] = 
    (program1IO, program2IO).parMapN{case (a,b) => a ++ b}

Чтобы понять почему ConnectionIO не позволяет делать что-то параллельно, я просто процитирую tpolecat:

Вы не можете запустить ConnectionIO параллельно. Это язык, описывающий использование соединения, которое представляет собой линейную последовательность операций.

Используя parMapN в IO, да, вы можете запускать две вещи одновременно, потому что они работают в разных соединениях.

Нет parMapN с ConnectionIO, потому что у него нет (и не может) быть экземпляра Parallel.

Другие вопросы по тегам