This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2024-02-26
Channels
- # announcements (19)
- # babashka (27)
- # beginners (24)
- # calva (14)
- # clerk (5)
- # clj-commons (21)
- # clojure (51)
- # clojure-europe (14)
- # clojure-madison (1)
- # clojure-nl (1)
- # clojure-norway (9)
- # clojure-uk (4)
- # clojuredesign-podcast (32)
- # core-async (14)
- # datomic (7)
- # events (1)
- # honeysql (3)
- # hyperfiddle (14)
- # introduce-yourself (2)
- # kaocha (7)
- # malli (21)
- # off-topic (50)
- # portal (2)
- # reagent (41)
- # reitit (41)
- # releases (1)
- # scittle (6)
- # shadow-cljs (90)
- # tools-deps (10)
- # xtdb (1)
- # yamlscript (1)
Hi I’m definitely under-qualified to even be thinking about this, but I have to ask. What are the downsides of replacing core.async/go with something like this:
(defmacro go
[& body]
`(let [ch# (a/chan 1)
captured-bindings# (Var/getThreadBindingFrame)]
(CompletableFuture/runAsync
(^:once fn* []
(Var/resetThreadBindingFrame captured-bindings#)
(try
(let [ret# (do ~@body)]
(a/put! ch# ret#))
(finally (a/close! ch#))))
(Executors/newVirtualThreadPerTaskExecutor))
ch#))
Thread-pinning is one issue. Although Clojure 1.12 (Alpha 5) introduced changes to make pinning less likely in core code, there are still plenty of things "in the wild" that use Java's synchronized
and could pin vthreads to O/S threads. The MySQL database driver is currently pretty bad for this. So a lot would depend on what exactly your go-using code is doing -- esp. if you are using Clojure 1.11 or earlier.
@U04V70XH6 thanks for the explanation! Is there any practical reason to want to use these virtual threads?
There are plenty of practical reasons -- but the question is: what sort of work are you doing? vthreads work best for tasks with I/O (since that's where the park/resume hooks have been added in the JDK/JVM) rather than heavily CPU bound... but you wouldn't use regular go
blocks for I/O-based work.
So there's a sort of conflict between how you are supposed to use go
blocks and when you would want vthreads...
I use go-loops to wait for incoming messages for high-traffic websockets and process them once received. So it’s a mix of I/O and calculations.
The idea was to rewrite go and subsequently go-loop using vthreads, to use them. But I’m afraid of bugs 🙂
If not go-loops, what should I use for such work? @U04V70XH6
If you're using go
-loops already, and it works, that seems... fine?
Thing is I’m not sure it works. For example I’m now debugging a problem, where if I’m creating 3 parallel workloads everything works, but when I add fourth everything breaks. Although they are produced by the same function, so the only difference I can imagine is the number of futures used under the hood.
If you're waiting on I/O in go
blocks, that sounds like it runs contrary to recommended practices -- and you should be using threads instead.
So in your case, explicitly using vthreads would probably be a good thing -- but not by subverting how go
works 🙂
Maybe something like promesa? It seems to have similar API to core.async, but uses vthreads under the hood
No idea. I've never used promesa
.
Me neither. I’ll try and report 🙂