On Tue, Jun 30, 2009 at 10:10, Daniel B Lucraft<d...@fluentradical.com> wrote:
>
> I didn't think it was possible for the render agent to be interrupted
> like that. Isn't the point of the MVCC system that the render agent
> will see a consistent view of the world as it was when the render
> started? And that the ants can continue modifying the world during the
> render's processing but the render agent will not see any of it until
> it has completed it's transaction? It only reads the refs so it
> shouldn't ever retry.
>
> Sorry to jump in despite being inexperienced at this, but it makes me
> think I don't understand something correctly.
>


To demonstrate my point, I made the following changes to my copy of ants.clj:

----------------------- [[ patch on ants.clj ]] ----------------------------
Changes in HEAD
        Modified ants.clj
diff --git a/ants.clj b/ants.clj
index 5e2e012..43e3ba0 100644
--- a/ants.clj
+++ b/ants.clj
@@ -262,11 +262,14 @@
     (render-ant (:ant p) g x y)))

 (defn render [g]
-  (let [v (dosync (apply vector (for [x (range dim) y (range dim)]
-                                   @(place [x y]))))
+  (println "entering render")
+  (let [v (dosync (println "snapshotting world")
+                  (apply vector (for [x (range dim) y (range dim)]
+                                  @(place [x y]))))
         img (new BufferedImage (* scale dim) (* scale dim)
                  (. BufferedImage TYPE_INT_ARGB))
         bg (. img (getGraphics))]
+    (println "rendering world")
     (doto bg
       (.setColor (. Color white))
       (.fillRect 0 0 (. img (getWidth)) (. img (getHeight))))
@@ -278,7 +281,8 @@
       (.drawRect (* scale home-off) (* scale home-off)
                  (* scale nants-sqrt) (* scale nants-sqrt)))
     (. g (drawImage img 0 0 nil))
-    (. bg (dispose))))
+    (. bg (dispose))
+    (println "exiting render")))

 (def panel (doto (proxy [JPanel] []
                         (paint [g] (render g)))
--------------------- [[ end patch on ants.clj ]] --------------------------

After evaluating:

  (def ants (setup))
  (send-off animator animation)

I saw output like this:

  entering render
  snapshotting world
  rendering world
  exiting render
  entering render
  snapshotting world
  rendering world
  exiting render
  ...

After evaluating this, which starts up all the ants and the evaporator
thread:

  (dorun (map #(send-off % behave) ants))
  (send-off evaporator evaporation)

I'm now seeing this:

  entering render
  snapshotting world
  snapshotting world
  snapshotting world
  snapshotting world
  snapshotting world
  snapshotting world
  snapshotting world
  snapshotting world
  snapshotting world
  snapshotting world
  ...

Clearly "snapshotting world" is getting retried. This makes a certain
degree of sense from skimming LockingTransaction, which ultimately
implements dosync.

I'm *guessing* that it records a readPoint (a kind of transactional
'timestamp') when it starts working and makes sure that this readPoint
is never less than any consulted reference's (last modification)
point. Such a constellation indicates that the reference has been
changed since the start of the transaction.  To recover from this,
clojure does a retry. This it will do 10'000 times before giving up. I
don't believe I ever actually waited that long. ;-)

// ben

--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to