-
-
Notifications
You must be signed in to change notification settings - Fork 62
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
feat: Add loom Support. #159
Conversation
example/minimalApplicationWithLoom/app/src/MinimalApplicationWithLoom.scala
Show resolved
Hide resolved
fc79bd2
to
0340772
Compare
In Mill you use |
23e03e1
to
c6821b6
Compare
@lihaoyi I think this pr is ready now, seems the virtual thread only improves the performance when heavy blocking. |
@He-Pin looks good overall, please summarize your benchmark results into a short summary table to include in the documentation with a link back to this PR for people to view the full details |
@lihaoyi I have updated with a summary table and added another note about classloading |
Thanks @He-Pin, I'll leave the PR open a few more days to see if anyone else wants to comment before merging |
@sorumehta Hi, this pr is ready, would you like to take a look at this, thanks. |
@He-Pin Quick question: once this is merged, do virtual threads become the default execution method? Or this happens based on certain condition(s)? |
@samikrc thanks for intresting. Short answer: No. it will only enabled once
Because, with the current implementation of JDK, virtual threads can lead to deadlock if they are not configured properly, we encountered this in production when a virtual thread and platform threads both tried to load the same class The JVM team at Alibaba helped us with a tweaked AJDK, which will add one more carrier thread for this, and they backported the JDK24 features into AJDK21 too. So, virtual threads help us reduce 50% ygc and 10 pt CPU usage under heavy load. Our system is fully async, so we can only see these improvements. For any user who tries to use Virtual threads in production, I would suggest:
|
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.
Happy to see this PR 😍 Was curious and checked out the code. I've noticed one or two things.
globalLogger.exception(e) | ||
throw new UnsupportedOperationException("Failed to create newThreadPerTaskExecutor.", e) |
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.
exception is both logged and re-thrown.
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.
Yes, I'm throwing it on purpose.
If I understand this correctly the Related to this, if the user has specified |
@megri , Thanks.
|
@megri you can still override |
Yes, you can still override it with your loom-based executor. Thanks @sideeffffect and @megri for the review. |
1 to 3: Not sure what you mean here. Let's say we have something like this (simplified) class Main {
def threadFactory: ThreadFactory = … // users can override this to use virtual threads
private def namedThreadFactory(name: String, wrappedThreadFactory: ThreadFactory): ThreadFactory = {
val n = AtomicLong(0)
runnable =>
val t = wrappedThreadFactory(runnable)
t.setName(s"$name-${n.getAndIncrement()}")
t
}
def createExecutor(): Executor = { // users can override this to use too if they want different scheduling mechanics
Executors.newThreadPerTaskExecutor(namedThreadFactory("cask", threadFactory))
}
def defaultHandler = new ThreadBlockingHandler(createExecutor(), new Main.DefaultHandler(…))
} This also compiles on all java versions. Is something missing? |
That was my thought as well, so I'm wondering if it makes sense for the default to be to tell users to add those things. |
the code needs to works with Java 11 as well , you can took a look at pekko , If zio support loom, I think they need to do the same. |
50bd94f
to
d6cb0d5
Compare
@megri This method is only available on JDK 21. |
Granted, if the goal is to provide an out of the box no extra code needed solution this is the (only) way to go. If this is what's desired I have no objection, it's just now how I would expect to do it :)
Good catch, but easily replaceable with a SAM-implementation. Thank you for your patience explaining the thought process behind your choices. |
At $Work, where we provide a big jar to support Java 8/17/21, we are using the same trick. The IDE can't support multi-release jars very well. You can see in apache/pekko#1724 , that I have to using Reflect, where
Then it will not be a completed ExecutorService implementation. |
No but an |
@megri Yes, I think the current Cask may need something like a graceful shutdown; otherwise, an executor API is insufficient. |
Nice! One thing I came to think of while walking home this evening was if the default Undertow workers (threads) need to be adjusted somehow, seeing that the intent is to not use them. They are set as part of the edit: Setting the XnioWorker explicitly during Undertow configuration might also be a cleaner way of integrating the virtual thread executorservice: https://github.com/xnio/xnio/blob/3.x/api/src/main/java/org/xnio/XnioWorker.java#L1185-L1187 |
Thanks @megri and @sideeffffect for the review and discussion! @He-Pin just let me know when you're done with this PR and I'm happy to merge this and send you the bounty, |
@lihaoyi I think I'm done with this PR, actually this helped me to do more enhancement on Pekko too, thanks. apache/pekko#1724 Another question is, do you plan to switch out Undertown to Netty? I think with your current design, it's possible. Another feedback is as @megri mentioned, we may need to expose more options to users from Undertown, but that can be done in another PR. |
Thanks @He-Pin , will transfer the bounty using the same bank details we used for the last one |
OK, I have a HK HSBC account now too. |
Thanks god, cask is using Java 11, not Java 8. |
Motivation:
Add Loom support.
refs: #90 , again
Modification:
handlerExecutor()
and some helper methods for virtual threads.Result:
Virtual threads supported.
wrk
is needed to run the benchmarkResults of same 4 Carrier/Platform threads:
Some design choices:
--add-opens java.base/java.lang=ALL-UNNAMED
handleExecutor
directly too.