~zainab/blog

ref: 26a1999881d784f9cc3e2c0fdd1985585a645c8a blog/src/chapters/2022-02-12-cats-effect-ioruntime/snippets.md -rw-r--r-- 4.6 KiB
26a19998zainab-ali Remove the misplaced error outputted by mdoc 6 months ago

#sbt

ThisBuild / scalaVersion := "3.0.2"
ThisBuild / libraryDependencies +=
  "org.typelevel" %% "cats-effect" % "3.3.2"

#imports

import $ivy.`org.typelevel::cats-effect:3.3.2`

#setup

import cats.effect._
import cats.effect.unsafe._
import cats.effect.implicits._
import cats.implicits._

object Threading {

  val basicRuntime: IORuntime = IORuntime(
    compute = IORuntime.createDefaultBlockingExecutionContext("compute")._1,
    blocking = IORuntime.createDefaultBlockingExecutionContext("blocking")._1,
    scheduler = IORuntime.createDefaultScheduler()._1,
    shutdown = () => (),
    config = IORuntimeConfig()
  )

  def boundedRuntime(numThreads: Int): IORuntime = {
    lazy val lazyRuntime: IORuntime = {
      IORuntime(
        compute = IORuntime
          .createDefaultComputeThreadPool(lazyRuntime, numThreads, "compute")
          ._1,
        blocking =
          IORuntime.createDefaultBlockingExecutionContext("blocking")._1,
        scheduler = IORuntime.createDefaultScheduler()._1,
        shutdown = () => (),
        config = IORuntimeConfig()
      )
    }
    lazyRuntime
  }

  def time(work: IO[Unit]): IO[String] =
    work.timed.map {
      case (t, _) => s"The task took ${t.toSeconds} seconds."
    }
}
import Threading._

#snooze

val snooze: IO[Unit] = IO(Thread.sleep(2000L))

#run-snooze-no-runtime

time(snooze).unsafeRunSync()

#run-snooze

time(snooze).unsafeRunSync()(basicRuntime)

#snooze-list

val snoozes: List[IO[Unit]] = List(snooze, snooze)

#snooze-parallel

val parallelSnoozes: IO[Unit] = snoozes.parSequence.void

#snooze-parallel-run

time(parallelSnoozes).unsafeRunSync()(basicRuntime)

#snooze-parallel-thousand

val lotsOfSnoozes = List.fill(1000)(snooze).parSequence.void

#snooze-parallel-thousand-run

time(lotsOfSnoozes).unsafeRunSync()(basicRuntime)

#factorial

val factorial: IO[Unit] = {
  @scala.annotation.tailrec
  def go(n: Long, total: Long): Long =
    if (n > 1) go(n - 1, total * n) else total
  IO(go(2000000000L, 1)).void
}

#factorial-run

time(factorial).unsafeRunSync()(basicRuntime)

#factorial-io-parallelized

val factorials: IO[Unit] = List.fill(10)(factorial).parSequence.void

#factorial-io-parallelized-run

time(factorials).unsafeRunSync()(basicRuntime)

#runtime-available-processors

val numProcessors = Runtime.getRuntime().availableProcessors()

#factorial-io-parallelized-time-each

val timedFactorial: IO[String] = time(factorial)
val timedFactorials: IO[List[String]] =
  List.fill(20)(timedFactorial).parSequence

#factorial-io-parallelized-time-each-run

timedFactorials.unsafeRunSync()(basicRuntime)

#factorial-bounded-threadpool

time(factorials).unsafeRunSync()(boundedRuntime(2))

#factorial-time-bounded-threadpool

timedFactorials.unsafeRunSync()(boundedRuntime(2))

#factorial-time-bounded-threadpool-20

timedFactorials.unsafeRunSync()(boundedRuntime(20))

#factorial-time-bounded-threadpool-available

timedFactorials.unsafeRunSync()(boundedRuntime(numProcessors))

#snooze-10

val tenSnoozes: IO[Unit] = List.fill(10)(snooze).parSequence.void

#snooze-10-run

time(tenSnoozes).unsafeRunSync()(boundedRuntime(numProcessors))

#combined

val snoozeAndCompute: IO[Unit] = 
  List(factorials, tenSnoozes).parSequence.void

#combined-run

time(snoozeAndCompute).unsafeRunSync()(boundedRuntime(numProcessors))

#setup-bounded-runtime

def boundedRuntime(numThreads: Int): IORuntime = 
  IORuntime(
    compute = IORuntime.createDefaultComputeThreadPool(numThreads),
    blocking = IORuntime.createDefaultBlockingExecutionContext()
  )

#compute-threadpool

boundedRuntime(numProcessors).compute

#better-snooze

val betterSnooze: IO[Unit] = IO.blocking(Thread.sleep(2000L))
val tenBetterSnoozes: IO[Unit] =
  List.fill(10)(betterSnooze).parSequence.void

#better-snooze-run

time(tenBetterSnoozes).unsafeRunSync()(boundedRuntime(numProcessors))

#combined-blocking

val betterSnoozeAndCompute: IO[Unit] =
  List(factorials, tenBetterSnoozes).parSequence.void

#combined-blocking-run

time(betterSnoozeAndCompute).unsafeRunSync()(
  boundedRuntime(numProcessors)
  )