zio / zio-profiling

https://zio.dev/zio-profiling
Apache License 2.0
19 stars 6 forks source link

Example program does not terminate #252

Closed jeanmarc closed 9 months ago

jeanmarc commented 9 months ago

I am using Scala3 (3.3.0), ZIO (2.0.18), and ZIO Profiling (0.2.1) and try to run the causal profiler example from the readme.

When I run this app, it emits 1 log message about warmup and then hangs indefinitely (at least more than 30 minutes).

What am I doing wrong?


import zio.*
import zio.profiling.causal.*

object Main extends ZIOAppDefault {
  val fast = ZIO.succeed(Thread.sleep(400))
  val slow1 = ZIO.succeed(Thread.sleep(600))
  val slow2 = ZIO.succeed(Thread.sleep(200))

  val slow = slow1 <&> slow2
  val program = (fast <&> slow) *> CausalProfiler.progressPoint("iteration done")

  def run = CausalProfiler(iterations = 20, warmUpPeriod = Duration.fromSeconds(1)).profile(program.forever).flatMap(_.renderToFile("profile.coz"))

}

The main class is in an sbt module that has these dependencies:

ThisBuild / scalaVersion := "3.3.0"

lazy val profiler = project
  .in(file("profiler"))
  .settings(
    libraryDependencies ++= Seq(
      "dev.zio" %% "zio-profiling" % "0.2.1",
      "dev.zio" %% "zio" % "2.0.18"
    )
  )

(I get compiler errors when adding the compilerPlugin("dev.zio" %% "zio-profiling-tagging-plugin" % "0.2.1") to the libraryDependencies, so I omitted that one)

jeanmarc commented 9 months ago

Turns out, the issue is caused by not adding any CostCenter.withChildCostCenter statements (the plugin isn't working, so this needed to be done manually). Revised code works as expected:

import zio.*
import zio.profiling.causal.*
import zio.profiling.CostCenter

object Main extends ZIOAppDefault {
  val fast = CostCenter.withChildCostCenter("fast")(ZIO.succeed {
    Thread.sleep(400)
    println("A")
  })
  val slow1 = CostCenter.withChildCostCenter("slow1")(ZIO.succeed {
    Thread.sleep(600)
    println("B")
  })
  val slow2 = CostCenter.withChildCostCenter("slow2")(ZIO.succeed {
    Thread.sleep(200)
    println("C")
  })

  val slow = slow1 <&> slow2
  val program = (fast <&> slow) *> CausalProfiler.progressPoint("iteration done")

  def run = CausalProfiler(
      iterations = 20,
      warmUpPeriod = Duration.fromSeconds(1)
    ).profile(program.forever).flatMap(_.renderToFile("profile.coz"))
  //def run = program

}