2017-06-19 32 views
0

我想了解失敗的代理是否可以自動重新啓動。它不會出現在我的代碼示例中: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) 

我錯過了什麼嗎?

回答

0

的事情是,在點在那裏你請致電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) 
+0

我標誌着這是正確的答案,因爲它幫助我瞭解問題的真正原因,這意味着由此我明白了爲什麼@ AlanThompson的答案(即使用未來的)工作。 – Integralist

0

這似乎是一個未公開的要求,即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