【问题标题】:How to find out why a Clojure agent got into invalid state如何找出 Clojure 代理进入无效状态的原因
【发布时间】:2014-11-09 06:30:01
【问题描述】:

Clojure 允许使用set-validator! 根据某些规则检查代理的新状态是否有效。我的验证器发现由于某种原因代理的值设置为nil。但是,我不知道这是怎么发生的——有什么方法可以查明试图设置无效状态的操作吗?

【问题讨论】:

  • 你能分享一些代码吗?
  • 为什么不让您的验证器引发异常,或者使用堆栈跟踪记录?
  • 不幸的是,验证者似乎不知道导致无效状态的操作的起源。该操作被放入代理的队列中。我想知道是否可以将一些元数据附加到包含堆栈跟踪的操作 - 这在调试期间可能会有所帮助。

标签: clojure agent


【解决方案1】:

代理也可以与watches 一起使用,因此向记录所有状态转换的代理添加一个观察者是非常合理的,这样当出现问题时,您可以使用此日志来重播导致失败(希望由此解决问题)

user> (def x (agent 0))
#'user/x
user> (def states (atom []))
#'user/states
user> (add-watch x :state-logger (fn [& change] (swap! states conj change)))
#<Agent@1dff7647: 0>
user> (send x inc)
#<Agent@1dff7647: 0>
user> (send x dec)
#<Agent@1dff7647: 0>
user> (send x inc)
#<Agent@1dff7647: 1>
user> @states
[(:state-logger #<Agent@1dff7647: 1> 0 1) 
 (:state-logger #<Agent@1dff7647: 1> 1 0) 
 (:state-logger #<Agent@1dff7647: 1> 0 1)]

(take 200 ...) 放入观察者可能是明智之举,这样您只保留合理数量的状态(或使用环形缓冲区)

【讨论】:

  • 是的,这是一种很好的调试方式,但不能解决最初的问题,即不知道发出操作的确切代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-20
  • 1970-01-01
  • 2015-11-14
  • 2011-09-11
  • 2021-06-01
相关资源
最近更新 更多