Clojure でサービスの開発を始めたところです。サーバーのシャットダウンにアプローチする方法に少し迷っています。
Clojure 1.5.1 を使用しています。ロギングには、Timbre 1.5.3 を使用しています。ホットコード展開のために NREPL をサーバーに組み込みたいと考えています。
これは私の core.clj ファイルです。Core がメインで、「lein new app」が生成するアプリ シェルを使用しています。
(ns extenium.core
(:require [taoensso.timbre :as t]
[clojure.tools.nrepl.server :as nrs])
(:gen-class))
(def nrepl-server)
(defn start-nrepl-server []
(t/info "Starting nrepl server on port 8628")
(alter-var-root #'nrepl-server
(constantly
(nrs/start-server :port 8628)))
(t/info "Started nrepl server"))
(defn stop-nrepl-server []
(t/info "Stopping nrepl server")
(nrs/stop-server nrepl-server)
(t/info "Stopped nrepl server"))
(defn start []
(alter-var-root #'*read-eval*
(constantly
false))
(start-nrepl-server))
(defn stop []
(stop-nrepl-server))
(defn -main [& args]
(start))
「lein run」すると、nrepl-server が期待どおりに起動し、情報メッセージがターミナルに送られます。次に、Emacs の「nrepl」で接続します。問題ない。Emacs から "(extenium.core/stop)" を実行します。その時点で、Emacs に "Stopping nrepl server" メッセージが表示されます (標準出力がクライアントにリダイレクトされたことを意味します)。接続は (予想どおり) 終了し、「Stopped nrepl server」というメッセージは表示されません。罰金。
ターミナルを見て、「Stopping...」または「Stopped...」というメッセージが表示されません。代わりに、次の例外が発生します。
Exception in thread "nREPL-worker-0" java.lang.Error: java.net.SocketException: Socket closed
理想的には、次のものが必要です。
- NREPL クライアントからシャットダウンを開始できるようにします。例外なく、すべての NREPL クライアント接続を適切に閉じます。ターミナル (または最終的にはローテーション ログ ファイル) に向けられたログ メッセージでシャットダウンします。
- NREPL 接続の間、ログ出力をサーバー (ターミナルまたはログ) と NREPL 出力の両方に複製します。
- 着信 NREPL 接続に関する情報をキャプチャし、それらに名前を付け、接続および切断アクティビティをログに記録します。
- 最終的に、着信 NREPL 接続を認証します。
- 後で、実行するアクションを承認します。