我使用代理來操縱結構,但我沒有所有的副作用。Clojure,代理,缺乏副作用
所有的信息都被髮送(我已經打印並統計了它們),但有時候我沒有全部的副作用。好像並非我的所有功能都應用於代理的狀態,或者如果最後一次發送應用於以前的狀態。
我嘗試過使用doall,dorun但未找到解決方案,非常感謝任何幫助。
;; aux function for adding an element to a hashmap
(defn extend-regs [reg s o]
(let [os (get reg s)]
(if (nil? os)
(assoc reg s [o])
(assoc reg s (conj os o)))))
;; the agent's altering function - adding an element to the :regs field(a hashmap)
(defn add-reg! [d s o]
(send d (fn [a] (assoc a :regs (extend-regs (:regs a) s o)))))
;; Creating the agents, dct/init returns an agent
;; pds: data for fields
(defn pdcts->init-dcts! [pds]
(doall (map dct/init (map :nam pds) (repeat nil))))
;; Altering one agent's state, dct/add-reg sends an assoc message to the agent
;; d: agent, pd: data for fields
(defn dct->add-regs! [d pd]
(dorun (map (fn [s r] (dct/add-reg! d s r))
(:syms pd)
(:regs pd)))
d)
;; Going through all agents
;; ds: agents, pds: datas
(defn dcts->add-regs! [ds pds]
(dorun (map (fn [d pd] (dct->add-regs! d pd))
ds
pds))
ds)
編輯:========================================= ============
好吧,事實證明我只是沒有足夠等待我的線程完成他們的任務。現在的問題是如何監控我的代理。我怎麼知道隊列中有未完成的線程?我只找到swank.core/活動線程和類似的,但它們不是解決方案。
我還沒有測試過你的代碼,但是當你的函數被代理執行時你可能會得到一個異常。之後,代理將不會接受任何新命令並保持其狀態。您需要在代理上調用clojure.core/agent-error來返回異常,然後對異常執行clojure.repl/pst以獲取堆棧跟蹤。 – bmillare
Thx回覆!我在失敗的案例上嘗試了代理錯誤,但是我得到了nils,所以沒有例外。無論如何thx! – argonz