I wasn't satisfied with the various answers to both this thread and
the StackOverflow question, so I spent a bit more time digging; it
turns out this was a bug in the range implementation that was fixed in
1.9.0-alpha11. I've added a bit more details on StackOverflow [1]; the
full story is on the ticket [2].

[1] 
https://stackoverflow.com/questions/39054911/strange-behavior-of-clojure-ref/45919119#45919119
[2] https://dev.clojure.org/jira/browse/CLJ-1914

On 23 August 2016 at 13:09, Sergei Koledov <grey3...@gmail.com> wrote:
> Hello,
>
> I had a problem when I run the following code:
>
> (defn get-task [tasks]
>   (dosync
>     (let [task (first @tasks)]
>       (alter tasks rest)
>       task)))
>
> (defn worker [& {:keys [tasks]}]
>   (agent {:tasks tasks}))
>
> (defn worker-loop [{:keys [tasks] :as state}]
>   (loop [last-task nil]
>     (if-let [task (get-task tasks)]
>       (recur task)
>       (locking :out (println "Last task: " last-task))))
>   state)
>
> (defn create-workers [count & options]
>   (->> (range 0 count)
>        (map (fn [_] (apply worker options)))
>        (into [])))
>
> (defn start-workers [workers]
>   (doseq [worker workers] (send-off worker worker-loop)))
>
> (def tasks (ref (range 1 10000000)))
>
> (def workers (create-workers 100 :tasks tasks))
>
> (start-workers workers)
> (apply await workers)
>
> Description: I have several agents (100 in my case). Each agent running in a
> separate thread. All agents share the one ref with the collection of tasks
> (range of longs in my case). Each agent get tasks from the collection (in
> transaction) one by one until the collection becomes empty and then prints
> the last task which it handle. However, when I run this code it looks like
> the collection of tasks suddenly becomes empty and workers handle only
> portion of all tasks (average 25-40% of all number).
>
> This code behave as I expected, when I create only one agent or use explicit
> locking in get-task function:
>
> (defn get-task [tasks]
>   (locking :lock
>     (dosync
>     (let [task (first @tasks)]
>       (alter tasks rest)
>       task))))
>
> I run this code on the Clojure 1.8.0
> java version "1.8.0_91"
> Java(TM) SE Runtime Environment (build 1.8.0_91-b14)
> Java HotSpot(TM) 64-Bit Server VM (build 25.91-b14, mixed mode)
>
> Can anyone tell me, what am I doing wrong, or it really looks like a bug in
> the clojure STM?
> I already asked this question on stackoverflow.com
> (http://stackoverflow.com/questions/39054911/strange-behavior-of-clojure-ref),
> but so far nobody has been able to help me.
>
> P.S. Sorry for my english skill.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to