我的一个基于Clojure的项目使用netty(由aleph所需)Web服务器。 我在
服务器实例存储在Clojure的原子(atom)中,以便稍后可以停止它。
我使用Emacs和Swank直接在REPL上启动服务器,像这样(在使用
无论是编辑
解决方法如下:
1. 别忘了第一点,不要使用C-c C-k。否则需要杀掉swank进程(或重启emacs),以便在相同的端口号上启动服务器。
2. 运行
这样做存在两个问题:
1. 经常会忘记第一点,不小心按下
2.
如何在编辑-编译-重新启动的工作流程中最好地解决这两个问题?
web.clj
文件中启动服务器和其他组件,如下所示:(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的原子(atom)中,以便稍后可以停止它。
我使用Emacs和Swank直接在REPL上启动服务器,像这样(在使用
C-c C-k
编译web.clj
后):user> (myproject.web/initialize)
无论是编辑
web.clj
或其他相关的模块时,都必须记住不要使用C-c C-k重新编译web.clj
,因为由于新编译的模块中的原子(atom),正在运行的实例会消失(REPL中的原子)。解决方法如下:
1. 别忘了第一点,不要使用C-c C-k。否则需要杀掉swank进程(或重启emacs),以便在相同的端口号上启动服务器。
2. 运行
(myproject.web/reinitialize)
停止服务器,并重新加载模块,然后再次启动服务器。这样做存在两个问题:
1. 经常会忘记第一点,不小心按下
C-c C-k
。这会导致REPL中的服务器原子(atom)丢失,从而需要杀掉swank进程(或重启emacs)才能在相同的端口号上启动服务器。2.
:reload-all
没有像使用C-c C-k
那样友好地报告编译错误(不美观的回溯信息(traceback)与简洁的可点击的错误信息)。如何在编辑-编译-重新启动的工作流程中最好地解决这两个问题?