I know how to fire N concurrent http
calls wrapped in futures
. There is a thread pool defined. The N concurrent requests are executed on the threads in the thread pool. But if I had to replace Future
with cats.effect.IO
and obtain the same behaviour (10 concurrent requests), how should I go about doing that? How can I execute N IO
requests concurrently?
parMapN
is the easiest way:
val req1: IO[Response] = ???
val req2: IO[Response] = ???
...
val req10: IO[Response] = ???
(req1, req2, req3 ... req10).parMapN{ case (resp1, resp2, .... resp10) =>
/* do something with the responses */
}
2 Likes
parSequence
possibly, or parTraverse
.
import cats.effect.{IO, ExitCode, IOApp}
import cats.implicits._
import scala.concurrent.duration._
object App extends IOApp {
def request(n: Int) = IO.sleep(5.seconds) *> IO(println(s"request $n"))
def run(args: List[String]) =
(1 to 10).toList.map(request).parSequence.as(ExitCode.Success)
}
Isn’t it parMapN
if you want to execute them concurrently?
4 Likes
Yes, fixed!
1 Like
So, we don’t need to provide a thread pool executor here?
1 Like
It requires an implicit ContextShift[IO]
. You can build one from a thread pool executor, or get one elsewhere, for example the default one in IOApp
, which is backed by this ExecutionContext: https://github.com/typelevel/cats-effect/blob/series/2.x/core/jvm/src/main/scala/cats/effect/internals/PoolUtils.scala#L28
Full example with IOApp: https://scastie.scala-lang.org/aM3oMlbiTGe9OPAa4hMJLQ
2 Likes