Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Publicise the mbean traits #3813

Open
wants to merge 14 commits into
base: series/3.x
Choose a base branch
from

Conversation

samspills
Copy link
Contributor

This way they could be gotten/invoked via the java ManagementFactory / MBeanServer.

I'd like to follow this up by investigating #3038 and I'm pretty sure this won't interfere there but I'm mentioning it here in case I'm wrong 😅

cc @mpilquist

@samspills samspills self-assigned this Sep 8, 2023
Copy link
Member

@armanbilge armanbilge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This way they could be gotten/invoked via the java ManagementFactory / MBeanServer.

😅 how does one do this exactly? Might be a good snippet to add to (scala)doc to explain how to use these now-public interfaces.

private[metrics] trait CpuStarvationMBean {
trait CpuStarvationMBean {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, this one is in c.e.metrics package ...

private[unsafe] trait ComputePoolSamplerMBean {
trait ComputePoolSamplerMBean {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And the rest are in c.e.unsafe.metrics. I can see why (these metrics are on unsafe things) but I wonder if now that we are making it public we should make it more uniform. Not sure.

Also: should we seal these traits? That way we can add new things to them without breaking compatibility. e.g. ComputePoolSamplerMBean might get polling-system metrics in the future?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my PR #3317, I moved all metrics to the cats.effect.unsafe.metrics package.

But are metrics really unsafe? 🤔

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw, once we make *MBean traits public, my PR will be binary breaking, right?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. I think we should put it all under one package.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But are metrics really unsafe?

Technically yes: they are side-effectual interfaces.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • I can move the CpuStarvationMBean into unsafe.metrics for sure
  • same with sealing the traits, that makes sense to me!

@iRevive I don't want to make your changes difficult!! What is the status of your PR? Would it be better if I hold off on the publicising until after your changes are merged in?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@samspills I've updated my PR (merged the upstream).

The purpose of the PR is to make the metrics publicly available, so you can integrate them with third-party libraries (or systems).

For example, the Prometheus collector can publish compute metrics without relying on mbeans. Here is an oversimplified example #3317 (comment).
Or otel4s can get a native integration.

@armanbilge
Copy link
Member

Oh, btw this PR should be targeted to series/3.x. We can't make API changes in series/3.5.x.

@samspills samspills changed the base branch from series/3.5.x to series/3.x September 11, 2023 23:53
@samspills samspills closed this Sep 15, 2023
@samspills samspills reopened this Sep 15, 2023
@djspiewak
Copy link
Member

Can we merge this with HEAD so we get the CI calming changes?

@samspills
Copy link
Contributor Author

oh sorry about that! thanks @armanbilge <3

@samspills
Copy link
Contributor Author

samspills commented Sep 29, 2023

I think I've gotten everything publicised correctly but I still can't trigger it via an mbean proxy because of the hash that gets added to the bean name here

s"cats.effect.unsafe.metrics:type=LiveFiberSnapshotTrigger-$hash")

(I'm using the fiber snapshot as an example, but I believe all mbeans have a hash added to the name EDIT: for clarity, all cats-effect mbeans. Other mbeans I've looked at don't seem to follow this convention)

With that hash in place I still have to get the mbeans using a query like I did originally.

Maybe I'm just not familiar with mbeans (fact), but it's not clear to me why the hash is necessary? @armanbilge do you know? If it were removed then accessing the bean is a bit nicer:

def readFibersFromRuntimeNoHash: IO[String] = IO {                
  val fiberObjectName =                                           
    new ObjectName("cats.effect.unsafe.metrics:type=LiveFiberSnapshotTrigger")                                                             
  val server = ManagementFactory.getPlatformMBeanServer           
  val fiberBean = JMX.newMBeanProxy(                              
    server,                                                       
    fiberObjectName,                                              
    classOf[LiveFiberSnapshotTriggerMBean]                        
  )                                                               
                                                                  
  fiberBean.liveFiberSnapshot().mkString                          
}                                                                 

Or maybe I'm missing a better way to work with the mbeans?

@armanbilge
Copy link
Member

Maybe I'm just not familiar with mbeans (fact), but it's not clear to me why the hash is necessary?

If I had to guess: in case there are two or more IORuntimes in the JVM? I guess the hash helps to make it unique, but it actually doesn't guarantee that. I wonder if instead we can use a global AtomicLong counter. That is guaranteed to be unique, and in the happy path (one global runtime) it will always be 0 which should be nice enough for easy access. WDYT?

@armanbilge armanbilge added this to the v3.6.0 milestone Jan 11, 2024
@djspiewak djspiewak modified the milestones: v3.6.0, v3.7.0 May 23, 2024
@@ -39,7 +39,7 @@ private[unsafe] trait LocalQueueSamplerMBean {
def getHeadIndex(): Int

/**
* Returns the index into the circular buffer backing the monitored [[LocalQueue]] which
* Returns the index into the circular buffer backing the monitored `LoLcalQueue` which
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Returns the index into the circular buffer backing the monitored `LoLcalQueue` which
* Returns the index into the circular buffer backing the monitored `LocalQueue` which

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants