2011-09-29 52 views
5

我的一個基於Clojure的項目使用netty(aleph)要求的web服務器。我啓動服務器,以及其他成分,在文件是這樣的:從Clojure REPL重新啓動HTTP服務器的工作流程

(ns myproject.web) 

(def server (atom nil)) 

(defn initialize [] 
    (if @server 
    (println "Warning: already initialized") 
    (let [port 8001] 
     (println (format "Starting http://localhost:%s/" port)) 
     (swap! server (fn [_] (start-http-server 
          (wrap-ring-handler app-routes) 
          {:port port})))))) 

(defn shutdown [] 
    (when @server 
    (do 
     (println "Shutting down web server") 
     (@server) 
     (swap! server (fn [_] nil))))) 

(defn reinitialize [] 
    "Run this on the REPL to reload web.clj and restart the web server" 
    (myproject.web/shutdown) 
    (use :reload-all 'myproject.web) 
    (myproject.web/initialize)) 

服務器實例存儲在一個Clojure的原子,以便它可以在以後停止。

我用Emacs and Swank直接發動對REPL這樣的服務器(與C-c C-k編譯後):

user> (myproject.web/initialize) 

每當或其他相關的模塊進行編輯,我必須

  1. 請記住不要使用Cc Ck重新編譯,因爲持有運行實例的原子將從REPL消失(由於來自新編譯模塊的原子)。

  2. 運行(myproject.web/reinitialize)停止服務器,然後在重新啓動它之前重新加載模塊。

有兩個問題:

  • 我經常忘了點#1並按C-c C-k反正。這會導致REPL中的服務器原子丟失,導致必須殺死swank(或重新啓動emacs),以便我可以在相同的端口號上啓動服務器。

  • :reload-all不報告編譯錯誤像C-c C-k(醜陋的追溯與簡潔的可點擊錯誤)一樣友善。

如何在編輯 - 編譯 - 重新啓動工作流程中最好地解決這兩個問題?

回答

6

被刪除您可以

(defonce server (atom nil)) 

更換

(def server (atom nil)) 

這樣當你評估緩衝區將不會重新定義服務器。

2

對於您的第一個問題,您可以將原子存儲在不同的命名空間中,並且在加載時只會覆蓋原子,如果它尚未定義。把它在它自己的namepspace會阻止它被重裝,所有

相關問題