316 karma · joined October 4, 2014
There is no difference between OS threads and virtual threads in this scenario, and everything in Javalin is blocking (by default).
The `ctx.result()` method doesn't actually write anything directly, it sets a result that will be written later. If you add an "After" handler, this also happens before the request is written. When the request is finally written, it's written on the same thread, and it is a blocking operation.
There is a `RequestLogger` you can hook into that fires after the response has been written.
Yes, Javalin is built on top of Jetty.
- how do virtual threads fit into a web framework?
Most JVM web frameworks (Jetty included) have a thread based request lifecyle (one thread handles one request from beginning to end). The java.lang.Threads are extremely expensive (~1mb memory), while Virtual Threads are very cheap (~0mb memory). We also have another ThreadPool for JSON streaming, and one for writing async responses. Using Virtual Threads for these things reduces overall memory pressure.
- do virtual threads make debugging more difficult? (A more general JVM question, I suppose)
Not that I know, but I've never used this in production myself.
- any performance / readability benefit, or just a coolness factor?
The alternative here is java.lang.Threads, so primarily the memory footprint. There is no readability difference. When developing, you don't see this at all.
Thanks for clearing that up. Would adding a "from" be sufficient?
and it uses Virtual Threads (“Project Loom”) by default
and it uses Virtual Threads (from “Project Loom”) by default
We use reflection to build the Virtual Thread Factory if the user has Loom enabled in their enviroment: https://github.com/javalin/javalin/blob/master/javalin/src/m...
In fairness, I think you did copy the Java version. There's a little switch in the code boxes where you can toggle the language, if you switch to Kotlin you get the version with trailing closures :)
Edit: I'm an idiot, I see the snippet you mean now. It's been updated now, give it a minute.
> but with a very persistent project manager
Your partner? :D
Edit: I was looking at the wrong snippet, the offending snippet has been fixed.
val myQpInt = ctx.validatedQueryParam("my-qp").asInt().getOrThrow() // past, java + kotlin
val myQpInt = ctx.queryParam<Int>("my-qp").get() // kotlin now
var myQpInt = ctx.queryParam("my-qp", Integer.class).get(); // java now