I am trying to write a macro that creates a state in the ns that macro was called. I cannot get the ^:dynamic part working (compiler warnings telling me that it is not dynamic). Here is what I have:
(defmacro create-notification-listener [listener-name channel-name listener-fn]
`(defstate ^:dynamic ~listener-name
:start (create-notification-listener-conn ~channel-name ~listener-fn)
:stop (.close ~listener-name)))
and somewhere else:
(db/create-notification-listener *job-polling-job-listener* job-entities/job-update-channel notify-monitor!)
results in:
Warning: *job-polling-job-listener* not declared dynamic and thus is not dynamically rebindable, but its name suggests otherwise. Please either indicate ^:dynamic *job-polling-job-listener* or change the name. (campaignbot/scheduler/job_polling.clj:17)
@f.v.claus iff you really need this complexity.. of a macro within macro, you should use vary-meta
inside the macros to add to meta, and not a reader ^:dynamic
macro:
boot.user=> (defmacro foo [name] `(mount/defstate ~(vary-meta name merge {:dynamic true}) :start 42 :stop (println "stopping" ~name)))
#'boot.user/foo
boot.user=> (foo *job-polling-job-listener*)
#'boot.user/*job-polling-job-listener*
boot.user=> (mount/start #'boot.user/*job-polling-job-listener*)
{:started ["#'boot.user/*job-polling-job-listener*"]}
boot.user=> @#'boot.user/*job-polling-job-listener*
42
boot.user=> (mount/stop #'boot.user/*job-polling-job-listener*)
stopping 42
{:stopped ["#'boot.user/*job-polling-job-listener*"]}