2013-12-10 2 views
8

У меня есть верхний уровень core.async go loop. Я хочу, чтобы он работал бесконечно, по крайней мере, до тех пор, пока я не передам его, чтобы он остановился с CTRL-C или kill или аналогичным. Я в настоящее время использую java.lang.Runtime/addShutdownHook так:Изящно выйти из Clojure core.async go loop on kill

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

Вот мои проблемы:

  1. Если я начинаю REPL и (run) затем он начинает и работает в фоновом потоке. Когда я выхожу из REPL, я не вижу желаемого сообщения о завершении работы.

  2. Однако, когда я бегу от lein run, цикл хода выходит сразу и отображает «SHUTDOWN».

Ни то, что я хочу.

Я не обязательно ожидаю найти решение, которое работает для всех JVM. Я разрабатываю на Mac и развернуть в Ubuntu, поэтому я хотел бы, чтобы найти решение, которое работает для обоих:

  • Mac JVM: Java версии "1.7.0_45" Java (TM) SE Runtime Environment (сборка 1.7.0_45-b18) Виртуальная виртуальная машина Java HotSpot TM TM (сборка 24.45-b08, смешанный режим)

  • Ubuntu JVM: версия Java «1.7.0_25» Рабочая среда OpenJDK (IcedTea 2.3.10) (7u25-2.3.10-1ubuntu0.12.04.2) OpenJDK 64-разрядный сервер ВМ (сборка 23.7-b01, смешанный режим)

+0

Смотрите также: http://stackoverflow.com/questions/11709639/how-to-catch-ctrlc-in-clojure –

+0

Смотрите также: http://stackoverflow.com/questions/18612063/clojure- core-async-cpu-hangs-after-timeout –

ответ

4

go функция возвращает канал. Вы можете хотеть (close! chan) в выключенном крючке.

Если вы запустите lein run, вам понадобится основная функция, которая вызовет (run), чтобы начать прокрутку.

(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

Вы видите сообщение об отключении, когда вы (a) запускаете REPL; (б) запустить через «lein run»? –

+0

Нет сообщения о завершении работы в случае (a) 'lein repl', case (b)' lein run' does display shutdown – edbond

+0

Если я запустил отображение закрытия «lein trampoline repla» при выходе с 'Ctrl-D' или используя' (exit) 'function – edbond

-1

Что касается части 1: «Когда я выйти из REPL, я не вижу желаемого сообщения о завершении работы. " Я думаю, что поток отключения не подключен к консоли lein repl.

Относительно части 2: После того, как цикл цикла запущен, он работает в фоновом режиме. Поскольку основной поток выходит после создания блока go, программа выключается. Чтобы сделать цикл продолжительным, его необходимо поместить в нормальный loop. (Также лучше сделать Thread/sleep внутри!)

+1

Блоки go не запускаются в потоках –

Смежные вопросы