Open
Description
I'm trying to ensure that my chained callbacks are always run on a specific thread pool, so I'm using d/onto
followed by d/chain
to set up the callbacks. What I'm seeing, though, is that sometimes the callbacks will be run directly on the derefing thread. I'm able to reproduce this behavior reliably (clojure 1.8, Java 1.8, manifold 0.1.6).
(require '[manifold.deferred :as d])
(import '(java.util.concurrent ForkJoinPool))
(defn tid []
(let [t (Thread/currentThread)]
(format "Thread %d: %s" (.getId t) (.getName t))))
(defn chained-onto-threads
"Tries n times to run f (which should produce a deferred) then chains the
result into a callback function that should run on the ForkJoinPool.
Returns a map containing the frequencies of threads that were actually used."
[n f]
(let [forkjoin-pool (ForkJoinPool/commonPool)
seen-threads (atom {})]
(run! deref
(for [i (range n)]
(-> (f)
(d/onto forkjoin-pool)
(d/chain
(fn [_]
;; Expecting this to be ForkJoinPool, but isn't always.
(swap! seen-threads update (tid) #(inc (or % 0))))))))
@seen-threads))
When I run chained-onto-threads
with an f
that produces a manifold future, sometimes the chained function runs on an nREPL thread, not a ForkJoinPool thread as expected:
user=> (require '[clojure.pprint :as pp])
nil
user=> (pp/pprint (chained-onto-threads 1000 #(d/future "any value")))
{"Thread 33: nREPL-worker-3" 7,
"Thread 35: ForkJoinPool.commonPool-worker-0" 142,
"Thread 37: ForkJoinPool.commonPool-worker-1" 123,
"Thread 38: ForkJoinPool.commonPool-worker-2" 160,
"Thread 39: ForkJoinPool.commonPool-worker-3" 144,
"Thread 40: ForkJoinPool.commonPool-worker-4" 143,
"Thread 43: ForkJoinPool.commonPool-worker-5" 163,
"Thread 45: ForkJoinPool.commonPool-worker-6" 118}
With an f
that produces a success-deferred
, the chained function always runs on an nREPL thread, not on the executor that was specified:
user=> (pp/pprint
#_=> (chained-onto-threads 1000 #(d/success-deferred "any value")))
{"Thread 15: nREPL-worker-1" 1000}
Can you shed any light on what's happening? Am I doing something wrong or is this a bug?
Metadata
Metadata
Assignees
Labels
No labels