Skip to content

Conversation

izeye
Copy link
Contributor

@izeye izeye commented Mar 11, 2025

This PR tries to support instrumentation for the Executors.newVirtualThreadPerTaskExecutor().

Closes gh-5488

Copy link
Member

@shakuzen shakuzen left a comment

Choose a reason for hiding this comment

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

Thanks for the pull request. I wonder how many users will want to run with --add-opens and if we should in some sense be encouraging that. At a minimum, we should document the limitation. I suppose there isn't another option now. I did mean to re-start conversations with the JDK team about providing some way to do this monitoring without illegal reflection access.

Signed-off-by: Johnny Lim <izeye@naver.com>
}

@Nullable
private static Method getMethodForThreadCountFromThreadPerTaskExecutor() {

Choose a reason for hiding this comment

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

Wouldn't it be better to generate a java.lang.invoke.MethodHandle once (maybe static) and use it (the same one, cached) in every call? Maybe it would be better for performance reasons

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@juliojgd Thanks for the feedback!

I'm not sure how easy implementing this with the MethodHandle would be, but it's not a hot spot, so I think it's okay as is.

Choose a reason for hiding this comment

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

IMHO, the gauge will call the method every N seconds, right? And the method in turn will make the reflective call each time, so maybe it could be a hotspot (due to the number of calls made during the JVM instance life).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@juliojgd I'm not familiar with the MethodHandle, so I'm not sure how effective it is here, but I attempted to switch to it in e5d159b.

}
catch (Throwable e) {
throw new RuntimeException(e);
}
}

@Nullable
private static Method getMethodForThreadCountFromThreadPerTaskExecutor() {
private static MethodHandle getMethodHandleForThreadCountFromThreadPerTaskExecutor() {
try {
Class<?> clazz = Class.forName(CLASS_NAME_THREAD_PER_TASK_EXECUTOR);

Choose a reason for hiding this comment

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

I think this could work

        Class<?> clazz = Class.forName(CLASS_NAME_THREAD_PER_TASK_EXECUTOR);
        // Get private access to the class
        MethodHandles.Lookup privateLookup = MethodHandles.privateLookupIn(clazz, MethodHandles.lookup());
        // Find the private method
        return privateLookup.findVirtual(clazz, "threadCount", MethodType.methodType(long.class));

Choose a reason for hiding this comment

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

with methodhandles in theory the accesscheck occurs only once (during the lookup) but with plain reflection the access check occurs in every invocation. At least this is my understanding

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@juliojgd MethodHandles.privateLookupIn() requires JDK 9+, but Micrometer needs to work on JDK 8, so we can't call it directly.

Copy link
Member

@shakuzen shakuzen left a comment

Choose a reason for hiding this comment

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

We should add something to the documentation about needing --add-opens for certain cases. But we can do that in a follow-up pull request.

@shakuzen shakuzen merged commit 124baac into micrometer-metrics:main Mar 17, 2025
9 checks passed
@izeye izeye deleted the gh-5488 branch March 17, 2025 10:04
izeye added a commit to izeye/micrometer that referenced this pull request Mar 17, 2025
shakuzen pushed a commit that referenced this pull request Mar 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Metrics for Executors.newVirtualThreadPerTaskExecutor()
3 participants