(defmacro consumer [[item] & body]
  `(agent
     (fn c# [~item]
       ~@body
       c#)))

(defmacro defconsumer [name item & body]
  `(def ~name (consumer ~item ~@body)))

(defn feed [consumer & values]
  (doseq [v values] (send-off consumer apply [v])))

Nine lines of code.

user=> (defconsumer foo [x] (println x))
#'user/foo
user=> (feed foo 7)
#<Agent #<user$c__1481__auto__ user$c__1481__auto__@1b030d8>>
user=> (feed foo 42 196)
#<Agent #<user$c__1481__auto__ user$c__1481__auto__@1b030d8>>

(and appearing at System/out)

7
42
196

I used send-off because your typical producer/consumer queue context
involves I/O- rather than CPU-bound work. Since agent sends from the
same thread are processed in the order sent, the whole thing works as
expected with one producer thread; with multiple producer threads the
inputs from separate threads will get interleaved but those from any
single one will be in sequence.

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