puniverse / pulsar

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

Exception when running skynet example #57

Closed mping closed 8 years ago

mping commented 8 years ago

Here's my skynet example:

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

(declare skynet)

(defsfn subnet [num size div]
  (loop [i 0
         children []]
    (if (= i div)
        children
        (recur
          (+ i 1)
          (conj children (fiber (skynet (int (+ num (* i (/ size div))))  ;;fiber blows up
                                        (int (/ size div))
                                        div)))
            ))))

(defsfn skynet [num size div]
  ;;(print (str "skynet " num "|" size "|" div "\n"))
  (if (= size 1)
      num
      (let [res (subnet num size div)
            joined (join res)]
        (->> res            
             join              ;;comment if not fiber
             (reduce +)))
      ))

(defn -main []
  (println (skynet 0 100 10)))

If I remove the fiber creation and the join call the code works, but using fibers I get a NPE exception somewhere. I'm a clojure newbie so I may be doing something wrong, but I cannot see where. Here's the stack:

Exception in thread "main" java.lang.NullPointerException, compiling:(/tmp/form-init2436751602057577490.clj:1:7[17/8407]
        at clojure.lang.Compiler.load(Compiler.java:7391)
        at clojure.lang.Compiler.loadFile(Compiler.java:7317)
        at clojure.main$load_script.invokeStatic(main.clj:275)
        at clojure.main$init_opt.invokeStatic(main.clj:277)
        at clojure.main$init_opt.invoke(main.clj:277)
        at clojure.main$initialize.invokeStatic(main.clj:308)
        at clojure.main$null_opt.invokeStatic(main.clj:342)
        at clojure.main$null_opt.invoke(main.clj:339)
        at clojure.main$main.invokeStatic(main.clj:421)
        at clojure.main$main.doInvoke(main.clj:384)
        at clojure.lang.RestFn.invoke(RestFn.java:421)
        at clojure.lang.Var.invoke(Var.java:383)
        at clojure.lang.AFn.applyToHelper(AFn.java:156)
        at clojure.lang.Var.applyTo(Var.java:700)
        at clojure.main.main(main.java:37)
Caused by: java.lang.NullPointerException
        at co.paralleluniverse.strands.Strand.park(Strand.java:493)
        at co.paralleluniverse.strands.ConditionSynchronizer.await(ConditionSynchronizer.java:54)
        at co.paralleluniverse.strands.dataflow.Val.get(Val.java:154)
        at co.paralleluniverse.fibers.Fiber.get(Fiber.java:1315)
        at co.paralleluniverse.pulsar.core$join_STAR_.invokeStatic(core.clj:434)
        at co.paralleluniverse.pulsar.core$join_STAR_.invoke(core.clj:430)
        at co.paralleluniverse.pulsar.core$join.invokeStatic(core.clj:468)
        at co.paralleluniverse.pulsar.core$join.invoke(core.clj:450)
        at clojure.core$map$fn__4785.invoke(core.clj:2644)
        at clojure.lang.LazySeq.sval(LazySeq.java:40)
        at clojure.lang.LazySeq.seq(LazySeq.java:49)
        at clojure.lang.RT.seq(RT.java:521)
        at clojure.core$seq__4357.invokeStatic(core.clj:137)
        at clojure.core.protocols$seq_reduce.invokeStatic(protocols.clj:24)
        at clojure.core.protocols$fn__6738.invokeStatic(protocols.clj:75)
        at clojure.core.protocols$fn__6738.invoke(protocols.clj:75)
        at clojure.core.protocols$fn__6684$G__6679__6697.invoke(protocols.clj:13)
        at clojure.core$reduce.invokeStatic(core.clj:6541)
        at clojure.core$reduce.invoke(core.clj:6527)
        at skynet.main$skynet.invokeStatic(main.clj:26)
        at skynet.main$skynet.invoke(main.clj:10)
        at skynet.main$skynet$fn__7297$fn__7298.invoke(main.clj:19)
        at co.paralleluniverse.pulsar.InstrumentedIFn.invoke(InstrumentedIFn.java:32)
        at co.paralleluniverse.pulsar.ClojureHelper.suspendableInvoke(ClojureHelper.java:213)
        at co.paralleluniverse.pulsar.ClojureHelper$4.run(ClojureHelper.java:200)
        at co.paralleluniverse.fibers.Fiber.run(Fiber.java:1027)
        at co.paralleluniverse.fibers.Fiber.run1(Fiber.java:1022)
        at co.paralleluniverse.fibers.Fiber.exec(Fiber.java:732)
        at co.paralleluniverse.fibers.FiberForkJoinScheduler$FiberForkJoinTask.exec1(FiberForkJoinScheduler.java:265)
        at co.paralleluniverse.concurrent.forkjoin.ParkableForkJoinTask.doExec(ParkableForkJoinTask.java:117)
        at co.paralleluniverse.concurrent.forkjoin.ParkableForkJoinTask.exec(ParkableForkJoinTask.java:74)
        at jsr166e.ForkJoinTask.doExec(ForkJoinTask.java:261)
        at jsr166e.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:988)
        at jsr166e.ForkJoinPool.runWorker(ForkJoinPool.java:1628)
        at jsr166e.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
circlespainter commented 8 years ago

The bug was triggered by joining a collection of fibers rather than one. You should lein install Pulsar locally and then depend on 0.7.6-SNAPSHOT.

mping commented 8 years ago

@circlespainter thanks for the quick fix, gonna give it a go.

mping commented 8 years ago

@circlespainter I installed pulsar locally from git, updated the dependency on project.clj but I still have the same error. Do I need to update quasar also?

I noticed my code has an unused expression joined (join res) but it shouldn't affect the bug. Here's a gist with the relevant files: https://gist.github.com/mping/c886851ec9001aa3a6b6d5494e7ed2ea

circlespainter commented 8 years ago

Oh, so you're using auto-instrumentation. If you remove it it works but of course it should work also with auto-instrumentation so I'll reopen the issue.

mping commented 8 years ago

Thanks, I tried without auto-instrumentation and its fine. I'll wait for the fix anyway.

circlespainter commented 8 years ago

Hi, it should work both with automatic and manual instrumentation now. You'll need to upgrade to Quasar 0.7.6-SNAPSHOT though and re-build and re-install Pulsar. Let me know if it works fine for you too.