2017-06-19 2 views
0

Ich versuche zu verstehen, ob ein fehlgeschlagener Agent automatisch neu gestartet werden kann. Es erscheint nicht so aus meinem Codebeispiel:Kann ein fehlgeschlagener Clojure-Agent automatisch neu gestartet werden?

(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) 

Fehle ich etwas?

Antwort

0

Die Sache ist, Sie an dem Punkt, wo Anruf restart-agent kein Neustart ist notwendig. Sie können dies anzeigen, indem Sie Ihren Handler zu diesem ändern:

Eine Ausnahme wird mit der Meldung 'Agent benötigt keinen Neustart' ausgelöst. Erst nachdem der Handler ausgeführt wurde, führt er :fail (oder :continue) aus.

Wissen Sie nicht, was Sie wollen, vielleicht einen Schrittmacher vorstellen?

(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

Ich markiere dies als die richtige Antwort, da es mir half, die eigentliche Ursache des Problems zu verstehen, was bedeutete, dass ich verstand, warum @ AlanThompsons Antwort (d. H. Mit einer Zukunft) gearbeitet hat. – Integralist

0

Es scheint eine nicht dokumentierte Voraussetzung zu sein, die in einem anderen Thread als die Fehlerbehandlungsroutine aufgerufen werden 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 
)) 

Mit Ergebnissen:

running in a thread... 
:01 => 1 
:20 agent error found: 
:21 restarting agent... 
:22 agent restarted, state= 200 
:02 => 200 
:03 => 201 
Verwandte Themen