-
Notifications
You must be signed in to change notification settings - Fork 150
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
support jdk9 forkjoinpool maximum-pool-size #485
Conversation
actor/src/main/scala/org/apache/pekko/dispatch/ForkJoinPoolConstants.scala
Outdated
Show resolved
Hide resolved
asyncMode: Boolean) = this(threadFactory, parallelism, asyncMode, ForkJoinPoolConstants.MaxCap) | ||
|
||
private lazy val pekkoJdk9ForkJoinPoolClassOpt: Option[Class[_]] = | ||
Try(Class.forName("org.apache.pekko.dispatch.PekkoJdk9ForkJoinPool")).toOption |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add a util to read the current jdk version instead, try pekko.util.JavaVersion
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because of the way Pekko builds the Java9+ classes, even the unit tests seem not to have this class available. It does eventually get built and appears in the jar.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
private lazy val pekkoJdk9ForkJoinPoolHandleOpt: Option[MethodHandle] = {
if (JavaVersion.majorVersion >= 9) {
pekkoJdk9ForkJoinPoolClassOpt.map { clz =>
val methodHandleLookup = MethodHandles.lookup()
val mt = MethodType.methodType(classOf[Unit], classOf[Int],
classOf[ForkJoinPool.ForkJoinWorkerThreadFactory],
classOf[Int], classOf[Thread.UncaughtExceptionHandler], classOf[Boolean])
methodHandleLookup.findConstructor(clz, mt)
}} else None
}
how about this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you try this yourself? I explained above that the build is weird - adding the java 9+ classes very late. After the unit tests run. Meaning we need to not rely on the classes being there. This change will fail multiple tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at this again on my phone - it will probably be ok. Looks the same as existing code with an additional jdk version check. The existing code works - it just relies n checking if a class loads ok.. In the full lifetime of the JVM we will try to class load once.. Java 8 users who only ever create one dispatcher will see a small perf boost. Everyone else will see a perf decrease because of the extra if check on every dispatcher create call.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added the java-version check because it happens inside the lazy val calculation - see we won't check this over and over.
actor/src/main/scala-jdk-9/org/apache/pekko/dispatch/PekkoJdk9ForkJoinPool.scala
Show resolved
Hide resolved
We are using Pekko now, and all of our nodes are running on Java 21, I would like to see this feature be shipped in 1.1.x. |
I don't think this is possible to do properly without multi-release-jar which is hitting problems |
Why? Netty can support multi jdk just with some feature tags. If that method is not called, no problem, we can built a release with jdk 11. |
This code can be written using Java reflection. The PR as it stands uses Java reflection. |
I think we should go with methodHandle, this can be done whiteout the multi release jar support. I did something like that in #666 This feature will make our 1.1.0 release shiny |
Better with method handle, on Java 17+, we need an addition add opens, the less reflections the better,we should move on prepare for future Java releases. |
I've changed the PR to use a MethodHandle. |
@mdedetrich He Pin wants this in v1.1.0. I'm neutral on this. Is it ok to use MethodHandles like this and rewrite later when we have Multi-Release jar support? |
@pjfanning I want this because it will address production runtime issue especially when user is blocking the actors. We have something like this in our production code with Virtual Thread too, If you want to defer this to 1.2.x/ 2.0.x that's fine, but this will be a killer feature in 1.1.x. |
actor/src/main/scala/org/apache/pekko/dispatch/ForkJoinPoolConstants.scala
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm at the first round , just a little nitpick , I think we should enable run test on JDK 21 too, if the code is target to higher JDK version.
We do test with java 21. Check the nightly builds |
The code is well done, and the last part should be update the document, that can come up later too. |
I would be more comfortable putting this in 1.1.0-M2 or maybe 1.2.0 as we are already overloaded with changes and we have just created a regression with JDK |
@He-Pin out of interest, is there a reason why you can't create a custom dispatcher that supports java9+ fork-join-pool? Such an approach would work today, no reason to wait for a Pekko 1.1 release. |
I'm fine to postpone this to later version eg 1.1.0-m2 or m3 , and I can help to test it. @mdedetrich @pjfanning feel free change it to 1.1.0-m2 |
@He-Pin Argument would be a lot more convincing if creating a JDK 9 The reason I am hesitant is that the current Pekko build with all of the JDK9 classes, multi-jvm etc etc is a bit of a mess, note that I am NOT blaming anyone specifically here, there are legitimate reasons for this, i.e. Akka was a really old sbt project that had to implement various workarounds which are no longer needed but those workarounds were still left in the code and then there is the case of working around even current day sbt limitations which is what is causing the sbt-osgi/sbt-multi-jar problems. In short I would like to start devoting actual effort to cleaning up the sbt build which is something that I have already initiated rather than dumping additional features that involve non trivial changes to the sbt build which then end up causing regressions (either at the start or later down the track due to how the sbt build interactions work). sbt-osgi is a good example of this, I took initiate/responsibility to get it working and as you can see we are still getting problems 3-4 months down the track. We need to be more strategic/intelligent about what features we push and for this feature specifically I would prefer if we actually put it on hold until I figure out and then stabilize all of the sbt-multi-jar/sbt-multi-jvm/sbt-osgi interactions. I know that the feature is important to others, but we need to prioritize the stability of the project and Pekko 1.1.x doesn't need to be perfect/have every feature we want, no one wins if we burn OS developers in trying to achieve that. To put things into perspective, this build complexity/maintenance burden was actually one of the reasons why Lightbend ended up making Akka commercial, their engineers couldn't handle all of the effort that was required so we need to be wary of that. I am doing my best to simplify the Pekko build so we don't have these same issues that Akka maintainers were dealing with but I can't really do that while we keep on dumping more high priority features that require significant changes to the sbt build. |
Yes, I want to polish the toolchain too. WDYT, a document still needs to be done to ship this. but the code should be mostly ready. |
If 1.1.0-M2 happens and it takes a long time because of other reasons then it can still land for 1.1.0 but to make it clear, we shouldn't delay 1.1.0 just for this feature. I would also prefer to implement this properly using multi-jar-release rather than reflection. |
That's true, I expect 1.1.0-M1 to be released soon, and I will not submit any feature pr before the 1.1.x branch cut. |
Update PekkoJdk9ForkJoinPool.scala Update ForkJoinPoolConstants.scala scala 2.12 compile issue review comments use methodhandle review comments
Update PekkoJdk9ForkJoinPool.scala
@He-Pin would you support having this in v1.1.0 ? |
Yes, I would like to have it ,even in m1. |
@mdedetrich can we merge this? I can rewrite this in another release to use Multi-Release jar support. The impl is private and controlled solely by config so it is easy to just completely rewrite it. We can document that the current support is experimental. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm, as long as we can improve on it later without breaking backwards compatibility
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
fork-join-executor.maximum-pool-size
config has no effect if you use Java 8 but has an effect if you use a newer JDFK.