Implement IORuntimeMetrics#3317
Conversation
IORuntimeMetricsIORuntimeMetrics
core/jvm/src/main/scala/cats/effect/unsafe/metrics/CpuStarvationSamplerMBean.scala
Outdated
Show resolved
Hide resolved
core/shared/src/main/scala/cats/effect/unsafe/IORuntimeMetrics.scala
Outdated
Show resolved
Hide resolved
c10bee1 to
29ebdfa
Compare
|
And a small demo: Demoimport cats.effect.{IO, IOApp}
import cats.effect.std.Random
import cats.effect.unsafe.IORuntimeMetrics
import cats.syntax.foldable._
import scala.concurrent.duration._
object Test extends IOApp.Simple {
def run: IO[Unit] = {
IO.delay(print(runtime.metrics)).flatMap(IO.println).delayBy(500.millis).foreverM.background.surround {
Random.scalaUtilRandom[IO].flatMap { random =>
val a = random.betweenInt(10, 3000).flatMap { int =>
if (int % 2 == 0) IO.blocking(Thread.sleep(int)) else IO.delay(Thread.sleep(int))
}.start.replicateA(100)
a.flatMap(_.traverse_(_.join))
} >> IO.never
}
}
def print(metrics: IORuntimeMetrics): String = {
s"""
|Compute:
|workerThreadCount: ${metrics.compute.map(_.workerThreadCount())}
|activeThreadCount: ${metrics.compute.map(_.activeThreadCount())}
|searchingThreadCount: ${metrics.compute.map(_.searchingThreadCount())}
|blockedWorkerThreadCount: ${metrics.compute.map(_.blockedWorkerThreadCount())}
|localQueueFiberCount: ${metrics.compute.map(_.localQueueFiberCount())}
|suspendedFiberCount: ${metrics.compute.map(_.suspendedFiberCount())}
|
|CPU Starvation:
|starvationCount: ${metrics.cpuStarvation.starvationCount()}
|maxClockDriftMs: ${metrics.cpuStarvation.maxClockDriftMs()}
|currentClockDriftMs: ${metrics.cpuStarvation.currentClockDriftMs()}
|""".stripMargin
}
}Output: |
core/jvm/src/main/scala/cats/effect/unsafe/IORuntimeMetricsCompanionPlatform.scala
Outdated
Show resolved
Hide resolved
|
Mima is sad: Since these classes were private to |
|
With #3526 the linking issue in ScalaJS is solved. |
djspiewak
left a comment
There was a problem hiding this comment.
Hey it only took me two years to get to this. New record?
Sorry. :( So the implementation overall looks good. I think this sort of thing is always somewhat clunky so that's fine. We should probably make the mbean paths consistent and just publish the change in the release notes (so people know to update any monitoring keys). The unsafe packages are similarly annoying but I think the optimal solution to this.
So long as all the mbean paths are made consistent, I'm pretty okay merging this. Anyone have any strong objections?
26a091d to
2be587d
Compare
IORuntimeMetricsIORuntimeMetrics
|
@djspiewak thanks for the review! Better late than never :) I changed the namespace of the CPUStarvation MBean to The names are the following:
|
|
Looks good! Once we sort the merge conflicts we can land it. |
2be587d to
9b7cd4c
Compare
|
Done. |
|
I think we should add metrics for the I'd also like to add polling system metrics. All polling systems should be able to support # of outstanding I/O operations. |
|
May we do this in the follow-up PR? The current PR is already big, and I would prefer to operate smaller changesets. Getting stats (at least the number of timers) from the abstract class PollingSystem {
def stats: PollingSystem.Stats
}
object PollingSystem {
sealed trait Stats {
def outstandingOperations(): Long
}
}That way, we can enforce implementations to provide metrics. I also found this one: #3686. |
There are a few notable notes regarding this PR:
CpuStarvationMBean somewhat breaks the consistency. All previous MBeans were undercats.effect.unsafe.metricspackage, whileCpuStarvationis available undercats.effect.metrics. I didn't update the MBean name yet.IORuntimeMetricsPlatform. For example, JVMIORuntimeMetricsofferscomputeandcpuStarvationmetrics. While JS and Native have onlycpuStarvation.Personally, the whole implementation feels clunky, hopefully we can find the right direction together.
This PR will not pass MiMa checks. Once we agree on a direction, I will address the bin compat issue.