【发布时间】:2011-11-28 00:00:48
【问题描述】:
我的一个基于 Clojure 的项目使用 netty(aleph 需要)网络服务器。我在 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 and Swank 像这样在REPL 上直接启动服务器(在使用C-c C-k 编译web.clj 之后):
user> (myproject.web/initialize)
每当编辑web.clj或其他依赖模块时,我必须
记住不要使用 C-c C-k 重新编译
web.clj,因为持有运行实例的原子会从 REPL 中消失(由于来自新编译模块的原子)。运行
(myproject.web/reinitialize)会停止服务器然后在重新启动之前重新加载模块。
这样做有两个问题:
我经常忘记第 1 点,然后按
C-c C-k。这会导致 REPL 中的服务器 atom 丢失,导致必须终止 swank(或重新启动 emacs),以便我可以在相同的端口号启动服务器。:reload-all不会像C-c C-k那样友好地报告编译错误(丑陋的回溯与简洁的可点击错误)。
在这个编辑-编译-重启工作流程中,我怎样才能最好地解决这两个问题?
【问题讨论】:
标签: clojure workflow read-eval-print-loop