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.