aleph 2025-03-18

is there a way to specify (adjust) the number of threads used by the server's event loop group?

@vale Thanks! As for using a virtual thread executor: this is probably the cause of your issue. Netty isn't really compatible with those, yet. See this thread where somebody else tried the same and ran into pretty much the same problem like you: https://clojurians.slack.com/archives/C0G922PCH/p1722257501702339

It also contains some pointers to how it might work these days, i.e. Netty recently added something that looks like it should support virtual threads.

But Aleph doesn't yet allow you to use that, I think

Patches welcome

well that's sad

as for the thread pinning: i believe that's resolved in jvm 24 if you can use it

even for synchronized?

@vale so you're on 24?

not yet but if you're telling me that aleph will work better with virtual threads on 24 i will

most of my workloads are massively io bound (remote api calls, db queries) so i'd benefit a lot from that

well so far the synchronized blocks are the main suspects but it's not certain

so dunno if this will really help but worth a shot

in start-server this seems to be hardcoded to (* 2 (.availableProcessors (Runtime/getRuntime)))

use case is that in a heavily io-bound workload using a virtual thread executor i don't want to be limited by the cpu core count

is this something that can be done with the bootstrap-transform option?

After a cursory investigation into the code, I don't think this is currently possible. There is https://github.com/clj-commons/aleph/blob/998a32a5ed9ada581fa73a389fbb0df43e8dd2d2/src/aleph/netty.clj#L1267 that could be used for this but the function that reads it is only used by clients...

For servers, it appears to be hardcoded

And Netty's MultithreadEventExecutorGroup (the relevant base class here) doesn't allow changing the thread count after instantiation.

(which would be a way to do it via bootstrap-transform)

@vale Would you mind filing a ticket for this? 🙏

Sure, but I'd also want to clarify if this is relevant at all with a newVirtualThreadPerTaskExecutor ? Thing is i've been seeing 502 errors (which I assume is aleph/netty refusing connections) when there's very minimal load and my only idea was that there's only one server thread (since the code runs on <1 vcpu) and so it can't accept any more (this using a virtual thread executor) But I don't understand the aleph/manifold execution model well enough (i was bitten by this when i assumed bindings in let-flow would get evaluated as if in separate futures)

I tried with bootstrap-transform but AbstractBootstrap does not allow changing .group once it's set