ring

2024-07-23T15:33:40.322289Z

For jetty is it recommended to use virtual threads? We have tried it out and we have noticed that sometimes after running our load tests the server just blocks and stops responding to all requests. Then if we disable virtual threads that doesn't seem to happen anymore. Also, it seems when using virtual threads our load tests perform worse. Any insights or things we should consider? We are just trying to optimize ring/jetty to handle as many requests per second as possible and as much concurrency as possible.

seancorfield 2024-07-23T16:21:02.793589Z

It's possible you're performing actions that pin virtual threads to O/S carrier threads -- that would cause thread starvation and blocking.

seancorfield 2024-07-23T16:21:51.124389Z

e.g., MySQL JDBC driver prior to 9.0.0 or something else that still uses synchronized.

2024-07-23T16:23:09.359409Z

Is there a way we can see what is causing threads to be pinned? We don’t use MySQL JDBC but we do use the Postgres driver

seancorfield 2024-07-23T16:23:20.617559Z

Virtual threads is well-suited to I/O heavy actions, rather than CPU heavy actions. But if your I/O is potentially a bottleneck -- such as a connection pool -- you can overrun it pretty easily with vthreads and you'll get timeouts etc.

seancorfield 2024-07-23T16:23:55.387739Z

Add the JVM option -Djdk.tracePinnedThreads=short (or full) and you'll see if there are pinned threads.

seancorfield 2024-07-23T16:25:36.985819Z

I'm still on the fence about vthreads. I was very excited about the idea of using them, but in practice it has been hard to find places where they would be useful, given the constraints of stuff like connection pools and HTTP throttling on external services.

2024-07-23T16:26:26.309649Z

Ok thanks. And yeah we just wanted to compare the performance in our load tests and see if how it compared.

seancorfield 2024-07-23T16:29:33.506809Z

And you're using Jetty 12 with which adapter?

2024-07-23T16:31:53.775039Z

[ring/ring "1.12.2"] [ring/ring-core "1.12.2"] [ring/ring-jetty-adapter "1.12.2"] [ring/ring-defaults "0.5.0"] [ring-cors "0.1.13"] [org.postgresql/postgresql "42.7.3"]

seancorfield 2024-07-23T16:32:15.456399Z

Ah, so that's Jetty 11 then.

seancorfield 2024-07-23T16:33:39.734539Z

Jetty 12 has a different architecture that might be more conducive to vthreads (with all the caveats above still in play) but I don't think I would want to try running Jetty 11 with a vthread per request...

2024-07-23T16:34:07.344229Z

Ah ok that could explain it then what other adapters could we test out?

seancorfield 2024-07-23T16:34:46.938259Z

This has a Jetty 12 version (despite its name): https://github.com/sunng87/ring-jetty9-adapter

2024-07-23T16:35:35.030099Z

Ok is that what your team uses? Is there any thing else to consider compared to the ring jetty adapter?

seancorfield 2024-07-23T16:36:08.572109Z

We tried it -- we'd been using the sunng87 adapter for quite a while to leverage Jetty 10/11 while Ring was still stuck on Jetty 9 -- but the real obstacle for us was a loss of observability in Jetty 12 as it was not fully supported by New Relic (we lost all "transaction" metrics).

seancorfield 2024-07-23T16:37:00.656089Z

We went back to the standard Ring adapter once it updated to Jetty 11 and had WebSockets built-in (another reason we had previously switched to sunng87 was its WebSocket support).

seancorfield 2024-07-23T16:37:31.451389Z

(New Relic has since improved Jetty 12 support so we may try it again once the default Ring adapter supports it)

2024-07-23T16:41:45.811289Z

Ok thanks I appreciate it. We will test it out and compare

seancorfield 2024-07-23T16:44:49.365279Z

Just remember that your database is probably going to be your bottleneck and load testing a regular thread pool based server will have inherent throttling to avoid overwhelming your DB (with appropriate tuning) but you lose that throttling with virtual threads so the behavior will be different and your load test may fail because of that...