I am running through the RabbitMQ tutorials on their web-page and as an exercise am trying to refactor the examples they provide to make them more general and composable. I am stuck on the second "blabbr" example. Here is the function I would like to refactor:
(defn -main
[& args]
(let [conn (rmq/connect)
ch (lch/open conn)
ex "nba.scores"
users ["joe" "aaron" "bob"]]
(le/declare ch ex "fanout" :durable false :auto-delete true)
(doseq [u users]
(start-consumer ch ex u))
(lb/publish ch ex "" "BOS 101, NYK 89" :content-type "text/plain" :type "scores.update")
(lb/publish ch ex "" "ORL 85, ALT 88" :content-type "text/plain" :type "scores.update")
(Thread/sleep 2000)
(rmq/close ch)
(rmq/close conn)))
I thought I could make a macro and call it in the function, like this:
(defmacro wrap-publish [default-exchange-name content mType data]
`(for [datum# data]
(lb/publish ch ex default-exchange-name datum# :content-type ~content :type ~mType)))
(defn -main
[...]
...
(wrap-publish default-exchange-name content-type mType data)
...
When I test the wrap-publish
macro by itself at the repl, however, I get this error:
java.lang.ClassCastException: clojure.lang.Var$Unbound cannot be cast to` com.novemberain.langohr.Channel basic.clj:89 langohr.basic/publish
It seems that there is something global going on that won't let me bind my vars, but I have no idea what. I followed my nose to the source-code thrown at me from the stack-trace, and hit a dead end there. I just don't know what to do. I am a new programmer taking baby steps into the world of async and macros. So I would appreciate any advice that would help me to not only accomplish my goal but also provide general insights that will inform my basic skills and let me know if I am taking the right approach. I am using the langohr dependency [com.novemberain/langohr "2.9.0"].