2011-09-29 91 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会阻止它被重装,所有