Clojure代理程序能否自动重启?
问题描述:
我想了解失败的代理是否可以自动重新启动。它不会出现在我的代码示例中:Clojure代理程序能否自动重启?
(def a (agent 0))
(defn h [a e]
(restart-agent a 0))
(set-error-handler! a h)
(send a inc)
;; 1
(send a #(/ % 0))
;; error handler h will be triggered
(send a inc)
;; ArithmeticException Divide by zero (agent didn't restart)
我错过了什么吗?
答
的事情是,在点在那里你请致电restart-agent
不需要重新启动。您可以通过将您的处理程序更改为:
(defn h [a e]
(try (restart-agent a 0)
(catch Exception e (println e))))
引发异常,说'代理程序不需要重新启动'。只有在处理程序运行后才能执行:fail
(或:continue
)。
不知道你在后,或许引进起搏器?
(def a (agent 0))
(def a-pacemaker (agent nil))
(defn h [a e]
(send a-pacemaker (fn [_] (restart-agent a 0))))
(set-error-handler! a h)
答
这似乎是一个未公开的要求,即restart-agent
在不同的线程比错误处理程序被调用:
(dotest
(future (println "running in a thread..."))
(let [agt (agent 0)
; This doesn't work
h01 (fn [a e]
(println :10 "agent error found:")
(println :11 "restarting agent...")
(restart-agent a 100)
(Thread/sleep 100)
(println :12 "agent restarted, state=" @a))
; This works. Need to call restart-agent in a separate thread
h02 (fn [a e]
(println :20 "agent error found:")
(future
(println :21 "restarting agent...")
(restart-agent a 200)
(println :22 "agent restarted, state=" @a))) ;=> 200
]
(set-error-handler! agt h02)
(send agt inc)
(Thread/sleep 100) (spy :01 @agt) ;=> 1
(Thread/sleep 100) (send agt #(/ % 0))
(Thread/sleep 100) (spy :02 @agt) ;=> 200
(Thread/sleep 100) (send agt inc)
(Thread/sleep 100) (spy :03 @agt) ;=> 201
))
有了结果:
running in a thread...
:01 => 1
:20 agent error found:
:21 restarting agent...
:22 agent restarted, state= 200
:02 => 200
:03 => 201
我标志着这是正确的答案,因为它帮助我了解问题的真正原因,这意味着由此我明白了为什么@ AlanThompson的答案(即使用未来的)工作。 – Integralist