Clojure: Managing throughput with virtual threads
andersmurphy.com
andersmurphy.com
On a related note, it would be nice to have an implementation of CSP using proper virtual threads rather than the thread pool currently used by core.async. The promesa library currently has a proof-of-concept[1], but it doesn't seem interoperable with existing core.async code.
[1] https://funcool.github.io/promesa/latest/promesa.exec.csp.ht...
Where I think things would get more complicated is if you wanted to control how bursty the token bucket is. You'd probably need another semaphore to limit the bursts etc.
This implementation is naive and does create a virtual thread for each permit that is waiting, so you have 2x the number of threads as you would have with a more complex implementation (i.e 1 per running task and 1 per waiting permit). This would be a no go with regular threads, but seems to work fine with virtual threads. It's pretty cool that virtual threads make naive implementations work.
Why not pool virtual threads, though? I get that they’re not scarce, but if you’re looking to limit throughput anyway wouldn’t that be easier to achieve using a thread pool than semaphores?
As to why use a semaphore over a thread pool for this implementation? A thread pool couples throughput to the number of running threads. A semaphore lets me couple throughput to started tasks per second. I don't care how many threads are currently running, I care about how many requests I'm making per second. Does that make more sense?
Is point 2 a virtual-thread only risk, or would we incur it with regular threads too?