Changing map to pmap in my Clojure program leads to weird exception (ClassCastException) -
as far know, pmap
in clojure works map
, calculates results in parallel, using futures under hood. should "just work" function , sequence, if map
works them. (unless there evil side effects prevent it, in case of program there nothing more loading data http server , transforming it)
, in case pmap
doesn't work expected. why can happen?
the problem arises here (if change map
pmap
): https://github.com/magicgoose/dvachmaster/blob/master/src/dvach/core.clj#l82
(defn thread-list "load threads pages, trying each page @ `max-trials` times `retry-inteval`" [board] (try (let [p0 (load-body (board-addr board 0)) numpages (count (:pages p0)) other-pages (map ; problem here (comp load-body (partial board-addr board)) (range 1 numpages)) all-pages (cons p0 other-pages) ] (doall ((comp (partial reduce concat) (partial map :threads)) all-pages))) (catch throwable e (.printstacktrace e))))
the exception get:
java.util.concurrent.executionexception: java.lang.classcastexception: java.lang.long cannot cast java.util.concurrent.future @ java.util.concurrent.futuretask$sync.innerget(unknown source) @ java.util.concurrent.futuretask.get(unknown source) @ clojure.core$deref_future.invoke(core.clj:2108) @ clojure.core$future_call$reify__6267.deref(core.clj:6308) @ clojure.core$deref.invoke(core.clj:2128) @ clojure.core$pmap$step__6280$fn__6282.invoke(core.clj:6358) @ clojure.lang.lazyseq.sval(lazyseq.java:42) @ clojure.lang.lazyseq.seq(lazyseq.java:60) @ clojure.lang.rt.seq(rt.java:484) @ clojure.core$seq.invoke(core.clj:133) @ clojure.core$map$fn__4207.invoke(core.clj:2479) @ clojure.lang.lazyseq.sval(lazyseq.java:42) @ clojure.lang.lazyseq.seq(lazyseq.java:60) @ clojure.lang.cons.next(cons.java:39) @ clojure.lang.rt.next(rt.java:598) @ clojure.core$next.invoke(core.clj:64) @ clojure.core.protocols$fn__6034.invoke(protocols.clj:146) @ clojure.core.protocols$fn__6005$g__6000__6014.invoke(protocols.clj:19) @ clojure.core.protocols$seq_reduce.invoke(protocols.clj:27) @ clojure.core.protocols$fn__6026.invoke(protocols.clj:53) @ clojure.core.protocols$fn__5979$g__5974__5992.invoke(protocols.clj:13) @ clojure.core$reduce.invoke(core.clj:6175) @ clojure.lang.afn.applytohelper(afn.java:163) @ clojure.lang.afn.applyto(afn.java:151) @ clojure.core$apply.invoke(core.clj:619) @ clojure.core$partial$fn__4190.doinvoke(core.clj:2396) @ clojure.lang.restfn.invoke(restfn.java:408) @ clojure.core$comp$fn__4154.invoke(core.clj:2331) @ dvach.core$thread_list.invoke(core.clj:91) @ dvach.core$eval3813.invoke(no_source_file:2) @ clojure.lang.compiler.eval(compiler.java:6619) @ clojure.lang.compiler.eval(compiler.java:6582) @ clojure.core$eval.invoke(core.clj:2852) @ clojure.main$repl$read_eval_print__6588$fn__6591.invoke(main.clj:259) @ clojure.main$repl$read_eval_print__6588.invoke(main.clj:259) @ clojure.main$repl$fn__6597.invoke(main.clj:277) @ clojure.main$repl.doinvoke(main.clj:277) @ clojure.lang.restfn.invoke(restfn.java:1096) @ clojure.tools.nrepl.middleware.interruptible_eval$evaluate$fn__1023.invoke(interruptible_eval.clj:56) @ clojure.lang.afn.applytohelper(afn.java:159) @ clojure.lang.afn.applyto(afn.java:151) @ clojure.core$apply.invoke(core.clj:617) @ clojure.core$with_bindings_star_.doinvoke(core.clj:1788) @ clojure.lang.restfn.invoke(restfn.java:425) @ clojure.tools.nrepl.middleware.interruptible_eval$evaluate.invoke(interruptible_eval.clj:41) @ clojure.tools.nrepl.middleware.interruptible_eval$interruptible_eval$fn__1064$fn__1067.invoke(interruptible_eval.clj:171) @ clojure.core$comp$fn__4154.invoke(core.clj:2330) @ clojure.tools.nrepl.middleware.interruptible_eval$run_next$fn__1057.invoke(interruptible_eval.clj:138) @ clojure.lang.afn.run(afn.java:24) @ java.util.concurrent.threadpoolexecutor.runworker(unknown source) @ java.util.concurrent.threadpoolexecutor$worker.run(unknown source) @ java.lang.thread.run(unknown source) caused by: java.lang.classcastexception: java.lang.long cannot cast java.util.concurrent.future @ clojure.core$deref_future.invoke(core.clj:2108) @ clojure.core$deref.invoke(core.clj:2129) @ dvach.core$load_body.invoke(core.clj:74) @ clojure.core$comp$fn__4154.invoke(core.clj:2331) @ clojure.core$pmap$fn__6275$fn__6276.invoke(core.clj:6354) @ clojure.core$binding_conveyor_fn$fn__4107.invoke(core.clj:1836) @ clojure.lang.afn.call(afn.java:18) @ java.util.concurrent.futuretask$sync.innerrun(unknown source) @ java.util.concurrent.futuretask.run(unknown source) ... 3 more
the problem stack trace complains @max-trials
on line 74; should read max-trials
instead. (max-trials
loop variable initialized @retry-count
on line 66; it'll number then, decremented on each iteration.)
it may arise intermittently, since point in code reached if try
block starting on line 68 fails fetch result.
Comments
Post a Comment