puniverse / pulsar

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

Exception: "co.paralleluniverse.actors.behaviors.ServerActor cannot be cast to co.paralleluniverse.actors.PulsarActor" when "receive" gets called in "handle-call" ("gen-server"-produced actor) #16

Closed circlespainter closed 10 years ago

circlespainter commented 10 years ago

I can't remember reading about it not being allowed (but I might have overlooked), Happens against current pulsar 0.4.0-SNAPSHOT in maven repos, quasar from local build (yesterday afternoon's 0.4.0-SNAPSHOT).

Code to reproduce it:

(ns test-receive-in-server
  (:require
    [co.paralleluniverse.pulsar.core :as pc]
    [co.paralleluniverse.pulsar.actors :as pa]))

(defn -main []
  (let
      [act
       (pa/spawn
         (pa/gen-server
           (reify pa/Server
             (init [_])
             (handle-call [self from id msg] (pa/receive [x] x)))))]
    (pa/call! act "msg")))

Full exception:

Exception in thread "main" java.lang.ClassCastException: co.paralleluniverse.actors.behaviors.ServerActor cannot be cast to co.paralleluniverse.actors.PulsarActor
    at co.paralleluniverse.actors.PulsarActor.currentActor(PulsarActor.java:39)
    at test_receive_in_server$_main$reify__1899.handle_call(test_receive_in_server.clj:13)
    at co.paralleluniverse.pulsar.actors$Server$reify__1827.handleCall(actors.clj:580)
    at co.paralleluniverse.actors.behaviors.ServerActor.handleCall(ServerActor.java:269)
    at co.paralleluniverse.actors.behaviors.ServerActor.handleMessage(ServerActor.java:209)
    at co.paralleluniverse.actors.behaviors.ServerActor.behavior(ServerActor.java:192)
    at co.paralleluniverse.actors.behaviors.BehaviorActor.doRun(BehaviorActor.java:275)
    at co.paralleluniverse.actors.behaviors.BehaviorActor.doRun(BehaviorActor.java:33)
    at co.paralleluniverse.actors.Actor.run(Actor.java:571)
    at co.paralleluniverse.fibers.Fiber.run(Fiber.java:905)
    at co.paralleluniverse.fibers.Fiber.run1(Fiber.java:900)
    at co.paralleluniverse.fibers.Fiber.exec1(Fiber.java:659)
    at co.paralleluniverse.fibers.Fiber.access$100(Fiber.java:64)
    at co.paralleluniverse.fibers.Fiber$FiberForkJoinTask.exec1(Fiber.java:1428)
    at co.paralleluniverse.concurrent.forkjoin.ParkableForkJoinTask.doExec(ParkableForkJoinTask.java:107)
    at co.paralleluniverse.concurrent.forkjoin.ParkableForkJoinTask.exec(ParkableForkJoinTask.java:69)
    at co.paralleluniverse.fibers.Fiber$FiberForkJoinTask.exec(Fiber.java:1502)
    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)
pron commented 10 years ago

It should be allowed. I'll fix it next week.

pron commented 10 years ago

In addition to removing the (stupid) requirement for the current actor to be a PulsarActor, this has also exposed a bug in instrumentation of protocols. Clojure may break up a single function into multiple inner classes. This was handled well for plain functions but not for reify. Now it's fixed.

Added test case:

(fact "Test receive in handle-call"
      (co.paralleluniverse.common.util.Debug/dumpAfter 5000 "foo.log")
      (let [actor (spawn #(receive
                           [from m] (! from @self (str m "!!!"))))
            gs (spawn
                 (gen-server (reify Server
                               (init [_])
                               (terminate [_ cause])
                               (handle-call [_ from id [a b]]
                                 (! actor @self (+ a b))
                                 (receive
                                   [actor m] m)))))]
        (call! gs 3 4)) => "7!!!")
pron commented 10 years ago

Uploaded fixed artifact to clojars.

circlespainter commented 10 years ago

That was a lot of work, thanks! Will try it out tomorrow

pron commented 10 years ago

Thank you! You've uncovered not one bug, but two!

circlespainter commented 10 years ago

Oh well, perhaps finding bugs is my talent then :D