如何找出Clojure代理进入无效状态的原因

如何找出Clojure代理进入无效状态的原因,clojure,agent,Clojure,Agent,Clojure允许使用设置验证程序根据某些规则检查代理的新状态是否有效。我的验证器捕捉到这样一种情况:由于某种原因,代理的值被设置为nil。但是,我不知道这是怎么发生的——有没有办法确定试图设置无效状态的操作?代理也可以使用,因此在代理中添加一个监视程序来记录所有状态转换是非常合理的,这样在出现问题时,您可以使用此日志来重播导致故障的转换(希望从中重演问题) user>(def x(代理0)) #'用户/x 用户>(def状态(atom[])) #'用户/状态 用户>(添加watch x:sta

Clojure允许使用
设置验证程序
根据某些规则检查代理的新状态是否有效。我的验证器捕捉到这样一种情况:由于某种原因,代理的值被设置为
nil
。但是,我不知道这是怎么发生的——有没有办法确定试图设置无效状态的操作?

代理也可以使用,因此在代理中添加一个监视程序来记录所有状态转换是非常合理的,这样在出现问题时,您可以使用此日志来重播导致故障的转换(希望从中重演问题)

user>(def x(代理0))
#'用户/x
用户>(def状态(atom[]))
#'用户/状态
用户>(添加watch x:state记录器(fn[&change](swap!states conj change)))
#
用户>(发送x公司)
#
用户>(发送x十二月)
#
用户>(发送x公司)
#
用户>@状态
[(:状态记录器#0 1)
(:状态记录器#1 0)
(:状态记录器#0 1)]

明智的做法是将
(取200…
)放入观察程序中,这样您只能保留合理数量的状态(或使用一个环形缓冲区)

您可以共享一些代码吗?为什么不让您的验证器引发异常,或使用堆栈跟踪记录?不幸的是,验证器似乎不知道导致无效状态的操作的起源。该操作被放入代理的队列中。我想知道是否可以将一些元数据附加到包含堆栈跟踪的操作-这在调试期间可能会有所帮助。是的,这是一种很好的调试方法,但并不能解决不知道发送操作的确切代码的原始问题。
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)]