Open jefrajames opened 3 months ago
Hi @jefrajames,
This project aims to become a module in the GlassFish project repository, so it depends on a snapshot version of GlassFish.
You can change the version of the glassfish-nucleus-parent
in pom.xml to the latest GlassFish version 7.0.15, the all should work.
As an alternative, you can also try building this executor from Grizzly: https://github.com/eclipse-ee4j/grizzly/pull/2185. It's not been merged yet into Grizzly because the Java 21 requirement, but it's usable and already more sophisticated than the executor in this project. For example, it supports max number of parallel virtual threads to limit resource usage.
Hi @OndroMih, thank you for your answer and the very interesting reading related to Grizzly issue and WebTide article. I agree with your proposal to limit the number of VT in the context of an App Server. According to my tests on Helidon (3 and 4) and Quarkus, using VT provides better performance (more throughput, less latency) while using less resource (CPU, memory) in most cases. I think that in the mid-term, running on VT should become the standard in App. Server. However, this may not be true for CPU intensive tasks. What about introducing a @RunOnPlatformThread annotation (the inverse of @RunOnVirtualThread currently provided by Quarkus) to allow the developper to decide?
Hi @jefrajames , you came to similar conclusions about VT performance as me in my experiments. VTs are faster with standard requests, which are I/O heavy, by about 10%. Meaning that just switching to VTs in GlassFish, GlassFish handled about 10% more requests per second. I guess that it's because context switching between VTs is much faster than between platform threads.
On the other hand, memory was not so simple. One thing is that platform threads pre-allocate a lot of memory, by default 1MB per thread. On my system, about 32k platform threads meant the system refused to pre-allocate more memory (about 32GB) and killed the process. But the real memory usage of platform threads was a bit smaller than memory used by VTs. That's when I simulated a stack trace with 100 nested methods, which is not uncommon in a Jakarta EE server. VTs store stacks in heap, which is less efficient than storing them in native memory, and it looked to me that VTs consumed about 20% more memory than platform threads. This is not so much an issue, because this is still only a fraction of the memory compared to what the application needs for business tasks, but it's interesting to know about it.
I also agree that VTs are not for CPU heavy tasks but one rarely sees CPU heavy tasks without any I/O in real world. And it's enough to log a statement, which is also an I/O operation, to switch a context to another thread and balance CPU usage between VTs. So it makes sense what you suggest to turn on VTs by default and enable switching to platform threads on a case by case basis. This will be possible with Jakarta EE 11 and the new version of Concurrency, which allows using executors services with or without virtual threads. VTs can be enabled by default, and tasks could be executed in an executor that uses platform threads.
After cloning the project on my laptop and running mvn install, I've got the following error: Non-resolvable parent POM for org.glassfish.main:grizzly-virtual-threads-pool:7.0.9-SNAPSHOT: The following artifacts could not be resolved: org.glassfish.main:glassfish-nucleus-parent:pom:7.0.9-SNAPSHOT (absent): Could not find artifact org.glassfish.main:glassfish-nucleus-parent:pom:7.0.9-SNAPSHOT and 'parent.relativePath' points at wrong local POM.
I think I miss something, but what?