Skip to content

Commit

Permalink
CpuStarvationCheck
Browse files Browse the repository at this point in the history
  • Loading branch information
Zschimmer committed Apr 23, 2024
1 parent 2302d03 commit e9670a8
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package js7.base.catsutils

import cats.effect.metrics.CpuStarvationWarningMetrics
import cats.effect.{IO, IOApp}
import js7.base.catsutils.CpuStarvationCheck.*
import js7.base.log.Logger.syntax.*
import js7.base.log.{LogLevel, Logger}
import js7.base.time.ScalaTime.*
import scala.concurrent.duration.{Duration, FiniteDuration}

transparent trait CpuStarvationCheck extends IOApp:

override def runtimeConfig =
super.runtimeConfig.copy(
cpuStarvationCheckInterval = cpuStarvationCheckInterval,
cpuStarvationCheckThreshold = cpuStarvationCheckThreshold / cpuStarvationCheckInterval,
cpuStarvationCheckInitialDelay = cpuStarvationCheckInitialDelay)

override protected def onCpuStarvationWarn(metrics: CpuStarvationWarningMetrics): IO[Unit] =
// See https://typelevel.org/cats-effect/docs/core/starvation-and-tuning
val d = metrics.starvationInterval * metrics.starvationThreshold
IO(logger.log(cpuStarvationCheckLogLevel,
s"🐌 Responsiveness was slower than ${d.pretty}"))



object CpuStarvationCheck:
/** Use only after Logger.initialize! */
private lazy val logger = Logger[this.type]

private val cpuStarvationCheckLogLevel: LogLevel =
sys.props.get("js7.cats.effect.cpuStarvationCheckLogLevel").fold(LogLevel.Info)(LogLevel(_))

private val cpuStarvationCheckInitialDelay: Duration =
if cpuStarvationCheckLogLevel == LogLevel.None then
Duration.Inf
else
sys.props.get("js7.cats.effect.cpuStarvationCheckInitialDelay").fold(60.s)(StringAsDuration)

private val cpuStarvationCheckThreshold: FiniteDuration =
sys.props.get("js7.cats.effect.cpuStarvationCheckThreshold").fold(100.ms)(StringAsDuration)

private val cpuStarvationCheckInterval: FiniteDuration =
sys.props.get("js7.cats.effect.cpuStarvationCheckInterval").fold(1.s)(StringAsDuration)
.max(cpuStarvationCheckThreshold)
7 changes: 5 additions & 2 deletions js7-base/jvm/src/main/scala/js7/base/catsutils/OurApp.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ package js7.base.catsutils

import cats.effect.IOApp
import cats.effect.unsafe.IORuntime
import js7.base.utils.Tests.isIntelliJIdea

trait OurApp extends IOApp:
trait OurApp extends IOApp with CpuStarvationCheck:

override protected final lazy val runtime: IORuntime =
override protected final lazy val runtime: IORuntime =
OurIORuntime.commonIORuntime

override protected def blockedThreadDetectionEnabled = isIntelliJIdea
2 changes: 1 addition & 1 deletion js7-base/shared/src/main/scala/js7/base/convert/As.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import js7.base.utils.DecimalPrefixes
/**
* @author Joacim Zschimmer
*/
trait As[V, W]:
trait As[V, W] extends (V => W):
// Objects of this class are implicitly used. So do not extend V => W to avoid implicit use as function.
def apply(v: V): W

Expand Down

0 comments on commit e9670a8

Please sign in to comment.