Hi Stefan,

The behavior you are seeing is not a problem, and understanding why may be 
helpful to using agents correctly.

The thread that sends to an agent has no guarantee that it will (or will not) 
see the result of its action a tiny bit later, when the repl prints the 
stringified version of the agent.

If you want to guarantee that your thread sees the results of its own sends, 
you can call await. To be sure you were seeing a bug, you would need to 

(1) create an agent
(2) have no other threads sending to the agent
(3) send something that caused an error
(4) await

Your example is missing step 4. When I tried it with step 4 included, the 
behavior was reliable. Of course that doesn't prove that there isn't a bug... 
:-)

Stu

> Hi,
> 
> I think I found a minor problem.  It appears with the error handling
> of agents and actually is just a minor glitch in the output.
> 
> Consider the following session, copied from a terminal:
> 
> shell> java -cp clojure.jar clojure.main
> Clojure 1.2.0-beta1
> user=> (def agt1 (agent "One"))
> #'user/agt1
> user=> (defn upd-agt1 [current new-val]
>       (if (= new-val "fail")
>         (throw (Exception. "Update failed."))
>          (str "Update: " new-val)))
> #'user/upd-agt1
> user=> (error-mode agt1)
> :fail
> user=> (send agt1 upd-agt1 "fail")
> #<ag...@21ed5459 FAILED: "One">
> 
> It creates an agent and causes an error in the update function.  The
> error mode of the agent is :fail and it silently fails when calling
> the action.  The failed status is visible from the printed output of
> the agent in the last line.  Further attempts to update the agent will
> raise an exception.
> 
> Now for a second version see the following session, which started
> fresh. It does the same thing as the first session, but it makes sure
> that the thread-pool for the agents contains more threads, first.
> 
> shell> java -cp clojure.jar clojure.main
> Clojure 1.2.0-beta1
> ;; this just creates some threads in the pool
> user=> (def agt2 (agent {:count 0}))
> #'user/agt2
> user=> (defn agt2-action [state]
>       (println "In Thread" (.getName (Thread/currentThread)))
>       (if (< (:count state) 5)
>         (do (send agt2 agt2-action)
>             (assoc state :count (inc (:count state))))
>          state))
> #'user/agt2-action
> user=> (send agt2 agt2-action)
> In Thread pool-1-thread-1
> #<ag...@4c6504bc: In Thread pool-1-thread-2
> In Thread pool-1-thread-3
> {:countIn Thread  pool-1-thread-4
> 1}>
> In Thread pool-1-thread-4
> user=> In Thread pool-1-thread-4
> ;; now the same as before...
> user=> (def agt1 (agent "One"))
> #'user/agt1
> user=> (defn upd-agt1 [current new-val]
>       (if (= new-val "fail")
>         (throw (Exception. "Update failed."))
>          (str "Update: " new-val)))
> #'user/upd-agt1
> user=> (error-mode agt1)
> :fail
> user=> (send agt1 upd-agt1 "fail")
> #<ag...@7f11bfbc: "One">
> 
> 
> This time the output doesn't show the FAILED status of the agent.
> 
> I am by no means sure that this change in behavior is related to the
> pool of threads.  I found it by accident and could reproduce it
> several times.
> 
> Kind regards,
> Stefan
> 
> -- 
> 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 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