I am toying with a simulation where I have couple of robots and a controller, controller decided what to do and assign jobs to robots, following is technically an abuse basically I do not care about the agents state, I just care about the fact that it will execute fns sent to it in order and I can wait for them to finish.
Following pretty much demonstrates what I am trying to achieve, controller gets a big job each robots gets a chunk of it,
(def *agents* (reduce
(fn[h v] (assoc h v (agent true)))
{:control (agent true)} (range 0 5)))
(defn send-job [id f]
(send-off (*agents* id)
(fn [s f]
(try
(f)
(catch Exception e (println e))))
f))
(defn await-job [id]
(await (*agents* id)))
(send-job :control
(fn []
(send-job 0 (fn []
(Thread/sleep 10)
(println "0 Done.")))
(send-job 1 (fn []
(Thread/sleep 2)))
(await-job 1)
;; 0 still running.
;; do other stuff...
))
Well the problem is you can not send-off from within a send-off I get "Can't await in agent action". Is it possible to do this using clojure's concurrency tools or do I have to re implement a agent like structure?
You can send or send-off from within an agent action all you like.
What you cannot, in fact, do, is await for another agent to complete, from within an agent. Just like the message says.
This is a good thing, since allowing to await in an agent obviously leads to possible deadlocks. The point of the clojure concurrency primitives is to make deadlock (and other concurrency-related problems) impossible, if you play by the rules.
IMO your use case is not ideal for agents. They are meant to be an asynchronous point of synchronization, similar to the the inbox queue
part of actors. Since you don't need that capability and use them as mere job runners, I think you will be served better with a plain Java ExecutorService.
Also of interest might be the ForkJoin framework, which basically is about forking off small units of a computation as you go and (possibly) waiting for them the moment you need the result.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With