我使用代理来操纵结构,但我没有所有的副作用。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