2013-12-10 17 views
8

Ho un alto livello ciclo core.async andare. Voglio che venga eseguito a tempo indeterminato, almeno fino a quando faccio segno di fermarsi con CTRL-C o kill o simili. Attualmente sto usando java.lang.Runtime/addShutdownHook come questo:garbo uscire da un Clojure core.async andare loop su uccidere

(ns async-demo.core 
    (:require [clojure.core.async :as async 
      :refer [<! >! <!! timeout chan alt! go]])) 
(defn run [] (go (loop [] (recur)))) 
(.addShutdownHook (Runtime/getRuntime) (Thread. #(println "SHUTDOWN"))) 

Qui sono i miei problemi:

  1. Se comincio il REPL e (run) poi inizia e viene eseguito in un thread in background. Quando esco da REPL, non vedo il messaggio di spegnimento desiderato.

  2. Tuttavia, quando corro da lein run, il ciclo go si chiude immediatamente e visualizza "SHUTDOWN".

Né è quello che voglio.

Non necessariamente aspetto di trovare una soluzione che funziona per tutti JVM. I sviluppare su un Mac e distribuire a Ubuntu, quindi mi piacerebbe trovare una soluzione che funziona per entrambi:

  • Mac JVM: versione java "1.7.0_45" Java (TM) SE Runtime Environment (build 1.7.0_45-b18) VM server Java HotSpot (TM) a 64 bit (build 24.45-b08, modalità mista)

  • Ubuntu JVM: versione java "1.7.0_25" OpenJDK Runtime Environment (IcedTea 2.3.10) (7u25-2.3.10-1ubuntu0.12.04.2) OpenJDK a 64 bit di server VM (build 23.7-b01, modalità mista)

+0

Vedi anche: http://stackoverflow.com/questions/11709639/how-to-catch-ctrlc-in-clojure –

+0

Vedi anche: http://stackoverflow.com/questions/18612063/clojure- core-async-cpu-hang-after-timeout –

risposta

4

go la funzione restituisce un canale. Si consiglia di (close! chan) nel gancio di arresto.

Se si esegue lein run è necessaria una funzione principale che chiamerà (run) per avviare il go thread.

(ns async-demo.core 
    (:require [clojure.core.async :as async 
      :refer [<! >! <!! timeout chan alt! go close!]])) 

(def ch (atom nil)) 

(defn run [] 
    (go (while true 
     (<! (timeout 500)) 
     (prn "inside go")))) 

(defn -main [& args] 
    (println "Starting") 
    (reset! ch (run)) 
    (.addShutdownHook (Runtime/getRuntime) 
        (Thread. #(do 
           (println "SHUTDOWN") 
           (close! @ch)))) 
    (while true 
    (<!! @ch))) 
+0

Si vede il messaggio di arresto quando si esegue (a) dal REPL; (b) eseguire tramite 'lein run'? –

+0

Non c'è nessun messaggio di arresto nel caso (a) 'lein repl', case (b)' lein run' visualizza shutdown – edbond

+0

Se eseguo 'lein trampoline repl' display di spegnimento quando esco con' Ctrl-D' o usando ' (uscita) 'funzione – edbond

-1

Per quanto riguarda la parte 1: "Quando esco dal REPL, non vedo il messaggio di spegnimento desiderato. " Penso che il thread di shutdown non sia connesso alla console di lein repl.

Per quanto riguarda la parte 2: Dopo aver avviato il ciclo Go, viene eseguito in thread in background. Poiché il thread principale si chiude dopo aver creato il blocco go, il programma si arresta. Per rendere il ciclo lunga durata, ha bisogno di essere messo in un normale loop. (È anche molto più bello inserire un Thread/sleep all'interno!)

+1

I blocchi go non vengono eseguiti nei thread –