【发布时间】:2017-05-13 14:36:02
【问题描述】:
我正在使用agents 设置处理链。我还希望有一个记录器来跟踪发生的事情。完整的代码在这里。
我可以看到 :charlie msg 已被处理,甚至在打印时转到 log 函数... 在被“发送”到“conj'ed”到记录器代理。
为什么查理从来没有出现在我的@logger 中?
(def logger (agent [])) ;; logger to keep track of what's done
(defn log [msg]
(send logger conj msg) ;; charlie's msg is NOT conj'ed
(println "logged" msg)) ;; but charilies msg IS printed
(defn create-relay [coll]
(reduce (comp agent vector) nil (reverse coll))) ;; see partial answer below
(defn relay-msg [next-agent prev-msg]
(if (nil? next-agent)
(log "finished relay")
(let [new-msg (str prev-msg (second next-agent))]
;; do something interesting with new-msg then:
(log new-msg)
;; go do the next thing
(send (first next-agent) relay-msg new-msg))))
(send (create-relay [:alice :bob :charlie]) relay-msg "hello")
(. java.lang.Thread sleep 5000)
(prn @logger)
输出:
logged hello:alice
logged hello:alice:bob
logged hello:alice:bob:charlie
["hello:alice" "hello:alice:bob"]
;; expected last line to be:
;; ["hello:alice" "hello:alice:bob" "hello:alice:bob:charlie"]
部分回答 我已经找到了使它起作用的方法,但我仍在寻找“接受”一个答案,该答案解释了错误隐藏在哪里。
打印是一个副作用。代理处于“一致”状态(无论这意味着什么)。在 "logging" charlie 之后,下一行在这一行中调用 "send to nil":
(send (first next-agent) relay-msg new-msg) ;; =>(first next-agent) is nil
似乎应该是NullPointerException,但它从未出现。因为在另一个线程里所以被吞了???
修复了以下难以理解的变化:
(reduce (comp agent vector) nil (reverse coll))
;; => change to =>
(reduce (comp agent vector) (agent nil) (reverse coll))
为什么对错误保持沉默?
@logging 回滚对吗?
如果回滚后还有其他项目“conj'ed”到 logging 怎么办?
我有“工作”代码,但我仍然对这里的正确行为感到迷茫。 “取消”记录某些内容听起来很可怕。
【问题讨论】: