Logging 记录Clojure代理
我正在使用设置处理链。我还想让一个记录员记录发生了什么。全部代码都在这里 我可以看到,Logging 记录Clojure代理,logging,clojure,Logging,Clojure,我正在使用设置处理链。我还想让一个记录员记录发生了什么。全部代码都在这里 我可以看到,:charlie消息被处理,甚至在打印时转到日志函数在被“发送”到记录器代理之后 为什么charlie从未出现在我的@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
:charlie
消息被处理,甚至在打印时转到日志
函数在被“发送”到记录器代理之后
为什么charlie从未出现在我的@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
回滚是正确的吗?如果在回滚后有其他项目“连接”到
日志记录中会怎样
我有“工作”代码,但在这里我仍然迷失在正确的行为上。“取消”-记录某些内容听起来很可怕。答案可以在以下网站上找到:
如果在功能执行期间进行了任何其他调度(直接或间接),则这些调度将一直保留到代理的状态发生更改之后
这里的“其他调度”本质上是指调用send
。因此,当为特定代理执行relay msg
时,对send
的所有调用都将排队,直到relay msg
返回代理的新状态。在:alice
和:bob
的情况下,一旦代理的状态更新,排队的发送将被调度
但是由于:charlie
上的中继消息
抛出空点异常
,因此:charlie
的代理将进入错误状态,并且队列中的发送
将被丢弃(包括对日志
的调用中的一个)
看起来它应该是一个NullPointerException,但它从未出现过。吞咽是因为它在另一根线里
有点。实际上,异常是由代理调度机制封装的。如果传递给send
的函数抛出异常,则会捕获该异常并将代理置于错误状态。异常存储在代理上,可以通过访问。(此外,对失败的代理的后续调用send
,会引发原始异常。)