Agent demo: leaves Clojure repl unquittable by EOF

2 views
Skip to first unread message

Stephen C. Gilardi

unread,
Mar 14, 2008, 2:39:51 AM3/14/08
to clo...@googlegroups.com
I ran an adapted version of the agent demo in the SVN 748 repl.  After doing so, I couldn't quit the repl with EOF (^D).  "^D" is echoed and the repl hangs:

Clojure
user=> (defn setup [n next]
  (if (zero? n)
     next
   (recur (dec n) (agent {:next next}))))
(defn relay [x m]
  (when (:next x)
    (send (:next x) relay m))
  (when (and (zero? m) (:report-queue x))
    (. (:report-queue x) (put m)))
  x)

(defn run [m n]
  (let [q (new java.util.concurrent.SynchronousQueue)
        tl (agent {:report-queue q})
        hd (setup (dec n) tl)]
    (doseq m (reverse (range m))
       (send hd relay m))
    (. q (take)))) 


#<Var: user/setup>
user=> #<Var: user/relay>
user=> #<Var: user/run>
user=> (time (run 100 100))
"Elapsed time: 609.281 msecs"
0
user=> ^D

--Steve

Rich Hickey

unread,
Mar 14, 2008, 8:14:17 AM3/14/08
to Clojure


On Mar 14, 2:39 am, "Stephen C. Gilardi" <scgila...@gmail.com> wrote:
> I ran an adapted version of the agent demo in the SVN 748 repl.
> After doing so, I couldn't quit the repl with EOF (^D). "^D" is
> echoed and the repl hangs:
>

The threads used by the agent system are not daemon threads, and thus
were keeping the process alive. I've added a System.exit call on EOF -
should quit normally now.

Rich

Darshan Shaligram

unread,
Mar 14, 2008, 8:40:23 AM3/14/08
to clo...@googlegroups.com

The exit() call on Repl EOF works well, but a Clojure script may spawn
a thread that it wants to leave running after loadFile() is done.
Instead of calling System.exit here, how about providing a function in
boot.clj (agent-pool-shutdown or something like that) that calls (..
clojure.lang.Agent pooledExecutor (shutdown)) and document that code
that uses agents must call that function when done processing?

Thanks,
Darshan

Rich Hickey

unread,
Mar 14, 2008, 9:28:56 AM3/14/08
to Clojure


On Mar 14, 8:40 am, "Darshan Shaligram" <scinti...@gmail.com> wrote:
You're talking about clojure.lang.Script, right? Yeah, I'm on the
fence.

I think code that spawns threads and needs to wait for them to
complete needs to use some coordination mechanism to do so. Agents
have await, there is CountDownLatch, CyclicBarrier, blocking queues
etc. Exposing the executors underlying the agents would give you other
tools - I'll look at that. But I'm not sure anything would get you out
of having the last line of a well-written multi-threaded script be a
wait-for-coordinated-termination of some sort.

Rich
Reply all
Reply to author
Forward
0 new messages