[Loom] Does junixsocket support virtual threads? #155
-
Hi, I have been trying to figure out to what extent junixsocket supports virtual threads which were stabilized in Java 21 (JEP-444). Unfortunately neither the javadoc nor website make any mention of this feature or how, if at all, it behaves together with junixsocket. Specifically I have two questions:
https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/net/Socket.html junisocket is, of course, not the default socket implementation. But it does offer "fake" sockets that behave like normal IP sockets except they pass their data through a unix socket instead. Does junixsocket offer similar interrupt functionality in those sockets? |
Beta Was this translation helpful? Give feedback.
Replies: 6 comments 1 reply
-
Hi @cenodis! Yes. Currently, junixsocket doesn't do anything special for virtual threads, so a blocking call with pin the underlying carrier thread. Adding support for virtual threads would be a nice contribution. Regarding interrupting at the Java level, and generally testing virtual threads, it would also be helpful to have some more unit tests as great start to dig into this topic. |
Beta Was this translation helpful? Give feedback.
-
@cenodis I have added some test code (MassiveParallelTest) and also improved the codebase for VirtualThreads with respect to Try the latest code (or junixsocket-selftest-2.10.0-20240415.192201-2-jar-with-dependencies.jar)
and compare the output for Java 17 and Java 21 (for example) In my testing on macOS, I was able to see a speed up of up to a factor of 6 when using VirtualThreads for the client connections, especially when using thousands/ten-thousands of client threads. While we should definitely currently pin threads (due to JNI), I don't see any messages even with In any case, now that we have some benchmarks, I'll be looking into adding support for kqueue/epoll to see if that makes some further difference. If you have other test cases, especially those where we get a "pinned thread" log message, please send them my way. |
Beta Was this translation helpful? Give feedback.
-
I have done some experimentation with both It does little more than listen on a unix socket in one (virtual) thread and read from said socket in another. But switching between SocketChannel and Junixsocket shows a clear difference in behaviour:
As for Unfortunately I have not yet found a way to make this class into a proper unit test. Outside of the jdk property there doesn't seem to be a way to ensure that both virtual threads are scheduled to the same carrier. All the ways to control either the scheduler or the virtual thread I have found are restricted as JDK interals. Another option might be to exhaust all other carriers on purpose to ensure deterministic assignment. But this also feels a bit too hacky and unstable to write a proper test against. Regarding possible solutions on the side of junixsocket:The "proper" fix is probably to do the same thing that Java did with its Socket: Implement the blocking semantics on top of non-blocking OS calls.
Now I have no experience with JNI so I don't know how much effort this change would be in this project. As a simpler, but less ideal fix one could also use a pool of platform threads to do the blocking:
This is less ideal because it does not fix the resource issue (you are still consuming a platform Thread for each native call). But it should fix the excessive carrier consumption and avoid interfering with other virtual threads. |
Beta Was this translation helpful? Give feedback.
-
Yes, converting the blocking into non-blocking + LockSupport seems to be the way forward. I will look into implementing support for kqueue (on macOS/BSD) and epoll (Linux), which are kind of required for this use case. On other platforms, I may leave the current, pinned/blocking strategy in place, at least for the time being (Solaris has its own /dev/poll device fwiw); maybe I will try a select() approach. If I'm not mistaken, I'll only need 1 platform thread to manage the kqueue/epoll event loop. |
Beta Was this translation helpful? Give feedback.
-
Having dug a bit further through the JVM code I am now almost certain that |
Beta Was this translation helpful? Give feedback.
-
@cenodis OK, I think I have managed to get it working correctly. Your test also appears to work as expected. |
Beta Was this translation helpful? Give feedback.
Continuing in #157