puniverse / pulsar

Fibers, Channels and Actors for Clojure
http://docs.paralleluniverse.co/pulsar/
Other
910 stars 53 forks source link

NPE when blocking in reduce fn (even with auto instrument) #42

Closed jjcomer closed 9 years ago

jjcomer commented 9 years ago

If making a blocking call in a reduce (or map) a NPE exception is thrown. Even with auto instrumentation turned on we are unable to instrument the reduce.

Here is a snippit which reproduces the issue:

(ns actors.test
  (:refer-clojure :exclude [promise await])
  (:require [co.paralleluniverse.pulsar
             [core :refer :all]
             [actors :refer :all]]))

(defsfn action-fn []
  (reduce (fn [acc v]
            (conj acc (join (fiber (inc v)))))
          [] (range 20)))

(defn start-test []
  (join (fiber (action-fn))))

I'm using JDK8 and clojure 1.7.0-RC2 with pulsar 0.7.1-SNAPSHOT

circlespainter commented 9 years ago

You should theoretically do '(suspendable! reduce)' and also create the lambda with sfn rather than fn if not using auto-instrumentation, but then Clojure reduce's runtime uses other anonymous functions that should be made suspendable too, so the best way to use standard Clojure's reduce with fiber-blocking code without writing an integration for it is indeed using auto-instrumentation.

Auto-instrumentation explicitly marks Clojure runtime not meant to be used in user calls as non-suspendable though, and it does so for efficiency's sake because this issue http://dev.clojure.org/jira/browse/CLJ-1645 makes it impossible to understand if an interface is a Java one or a Clojure protocol one (votes there are appreciated). reduce was being (wrongly) excluded from auto-instrumentation too, now it should be included instead.

jjcomer commented 9 years ago

Makes sense. Thanks @circlespainter