Fork me on GitHub
Alex Miller (Clojure team)22:11:43

org.clojure/core.async 0.5.527 is now available

👍 96
bubblebobble 8
Alex Miller (Clojure team)22:11:51

core.async 0.5.527 is now available. In general, you should never directly or indirectly use blocking IO operations in go block threads. The go block threads are a fixed pool of (by default 8) threads. If you block enough of these threads, you lock up the pool, potentially in unrecoverable ways. This release contains a new Java system property (intended primarily for development use) that will throw if core.async blocking operations (anything ending in "!!") are used in a go block. The exception will be thrown in a go block thread which by default will bubble up to the ThreadGroup's uncaught exception handler and get printed to stderr. You can also set Thread.setDefaultUncaughtExceptionHandler() if you want to do something else. Note that this only catches one set of blocking calls, other blocking IO is equally as problematic and will not be caught with this flag. Example:

clj -J-Dclojure.core.async.go-checking=true

user=> (require '[clojure.core.async :as a])
user=> (def c (a/chan 10))
user=> (a/go (a/>!! c 100))
#object[clojure.core.async.impl.channels.ManyToManyChannel 0x77a14911 "clojure.core.async.impl.channels.ManyToManyChannel@77a14911"]
user=> Exception in thread "async-dispatch-1" java.lang.IllegalStateException: Invalid blocking call in dispatch thread
    at clojure.core.async.impl.dispatch$check_blocking_in_dispatch.invokeStatic(dispatch.clj:29)
    at clojure.core.async.impl.dispatch$check_blocking_in_dispatch.invoke(dispatch.clj:26)
    at clojure.core.async$fn__6568.invokeStatic(async.clj:164)
    at clojure.core.async$fn__6568.invoke(async.clj:164)
    at user$eval9097$fn__9098$state_machine__6417__auto____9099$fn__9101.invoke(NO_SOURCE_FILE:1)
    at user$eval9097$fn__9098$state_machine__6417__auto____9099.invoke(NO_SOURCE_FILE:1)
When running source from a file, the NO_SOURCE_FILE lines will point to the offending file and line performing the blocking operation (here those on the REPL). Additionally, the pipeline api call has been modified, both to respect the policy above and to address issues with reusing the go block thread pool for pipeline concurrency (capped by go block thread pool size). The api docs have been regenerated:

💯 4

That's a great feature, thanks.


I think it would be fair to say that any go block should not do significant work and should quickly get to an IOC operation to release the thread it’s using


My rule of thumb is thread to do work go to do orchestration.

👍 28