5 ms·
I am looking forwarding to trying Nima. The blocker for me is IntelliJ supporting Java 21, which i believe will be this winter [1]; i don't absolutely need Inte
by twic 3y ago
I am looking forwarding to trying Nima. The blocker for me is IntelliJ supporting Java 21, which i believe will be this winter [1]; i don't absolutely need IntelliJ, but i am very lazy.
At the moment, my apps are using either the JDK HttpServer, which is easy to use, but of questionable robustness and lacking websocket support, or a Netty-based server, which works very well and supports websockets, but is often awkward to program against because it's asynchronous. Nima should combine a nice simple synchronous API with a fairly luxurious feature set and good scalability.
Of course, it will turn out there are things terribly wrong with it, because this is real life. But for now i'm optimistic!
[1] https://intellij-support.jetbrains.com/hc/en-us/community/posts/13049784815250-Planned-release-date-of-2023-3-with-Java-21-support https://intellij-support.jetbrains.com/hc/en-us/community/po...
- Two4 3y agoNon-MicroProfile Helidon uses a reactive interface for most things, which lends itself well to async operations. It a very nice, simple and powerful abstraction that makes async relatively easy. IMO anything webserver or client should be async when virtual threads aren't available, due to Java having the tendency to quickly build up a ton of threads when you use the one-thread-per-request model. That being said, virtual threads does make that model viable at scale, so reactive async probably isn't as necessary.
- strangemonad 3y agoI’ve had no problems scaling jetty to 400-500 qps per node on small thread pools.
- mikmoila 3y agoJetty can be used with virtual threads: https://webtide.com/jetty-12-virtual-threads-support/ https://webtide.com/jetty-12-virtual-threads-support/
- Two4 3y agoAs soon as you start talking thread pools, you're talking about async task dispatching at some level, even if it's abstracted away at the API level. What I'm talking about is using a virtual thread, not event-driven shuttling of stateful objects between threads via task queues, to complete a request from start to finish.
- twic 3y agoReactive APIs are horrible, and precisely what I'm trying to avoid.
- Svenskunganka 3y agoThe main problem I have with reactive programming in Java, at least with Project Reactor which is the only one I've used is the cryptic stack traces. You can regain some information by enabling runtime instrumentation to be used in development, but has too much of a performance hit to be used in production. It doesn't produce much better stack traces either. Trying to read a profiler flamegraph is nigh impossible for reactive code. For the debugger, you need to manually insert breakpoints in each step of the chain, because otherwise you'll just be looking around the reactive library's internal code. The other problems I have is that as soon as you need to do anything blocking (e.g talking to SQLite or RocksDB over JNI), the whole thing falls apart in terms of threading. Doing a HTTP request somewhere in a reactive chain that does some blocking operations - well shit now you're blocking the reactor-http-netty-* threads, which are fixed so you're worse off than with thread-per-request at that point. Or even just using Caffeine cache, or any caching library really, but Caffeine is one of few that prevents async stampede - well shit now you're running on ForkJoin pool during cache misses, but "reactive" threads on cache hits. You can see how this quickly becomes a tangled mess of thread-hopping and avoiding blocking event loops, and it's extremely complicated to get this right with how subscribeOn/publishOn works and how the profiler can't tell you which threads runs what code because the stack traces are filled with garbage. You also opt out of a lot of what Java offers in terms of synchronization. Using the synchronization keyword is a big no-no, the JVM can park the thread while waiting for the lock. Now that thread cannot schedule other tasks just because that one task ran into lock contention, and it's highly likely a fixed pool of threads. You're basically left with CAS, AtomicLong/AtomicBoolean/etc, and that's it. I've even seen BlockHound, project reactor's tool to help you find if you are blocking somewhere, trigger "Blocking call to LockSupport.park()!" during a ConcurrentHashMap lookup. Add to this that most caching libraries are implemented on top of ConcurrentHashMap. Getting async right in reactive code has a huge mental overhead and you need intricate knowledge of the libraries you depend on, the platform you run on and what it is that actually enables async in the kernel, and where it is unavailable. Good example of this; that UUID library you use uses a CSPRNG. Have you set the JVM flag to read it from the non-blocking /dev/urandom rather than the default /dev/random on Linux? I think reactive programming in Java is decent as long as all you're really doing is accepting/performing HTTP requests and talking to a database that has a reactive client connector. In essence, anything that strictly deals with networking, since that's all that can really be made truly async currently, thanks to epoll/kqueue/iocp on linux/mac/windows respectively. Hopefully io_uring will broaden that to file IO as well eventually, but unfortunately that's linux-only for now. Contrast this with Go's scheduler that just takes care of this for you - no need to think about it. Or Rust + Tokio, where it is explicit with tokio::spawn_blocking and offering async counterparts to std Mutex, RWLock, Channels, etc that doesn't block the current thread on lock contention.
- geodel 3y agoHelidon 4 is massive refactoring to support Java 21/ virtual thread from grounds up to the point that most reactive stuff is removed and replaced plain sync APIs.
- skinowski 3y agoThis is one of the things that bother me about Java; IDE dependency.
- pjmlp 3y agoIDE productivity, and it started with Smalltalk and Lisp Machines, was adopted by C++, Visual Basic and Delphi, among several 4GLs, several years before Java was invented. Everyone is free to use Java in vi with make, if they feel happy doing so. In fact, there were hardly any Java IDEs when the language was released in 1996, which were quickly provided by Smalltalk, Delphi and C++ vendors.
- saagarjha 3y agoJava is somewhat unique in how annoying the typical project is to work on without an IDE.
- pjmlp 3y agoAll languages are annoying to use without IDEs, unless we are talking about toy implementations. I became an XEmacs user in 1995, because everything else in UNIX just sucked in comparison with PC, Mac OS and Amiga IDEs of the time.
- saagarjha 3y agoI've worked on plenty of projects where I can navigate around in a pretty dumb text editor and run "make" and things mostly work. In Java land most things are several folders deep and things are injected in from places I don't understand without tooling to show me what is going on. I mean, have you tried using jdb? It basically exists as an advertisement for an integrated debugger.
- pjmlp 3y agoThat is what many call gdb as well, so it isn't far off. As for messy code navigation, I have similar experiences in large C codebases, so maybe C is also unusable without IDEs.
- gbear605 3y agoThe IntelliJ Early Access Program will be out sometime before then, if you’re willing to go for a potentially unstable IDE experience.
- twic 3y agoI feel like i have a sufficiently unstable IDE experience using the general availability releases!
- SpaghettiCthulu 3y agoI've been using intellij to write code that uses a Java 21 or 22 dev build for months. Do you perhaps mean support for running the IDE itself on Java 21?
- re-thc 3y ago> The blocker for me is IntelliJ supporting Java 21 Pretty sure this works with Java 20 with the loom previewed enabled.