【问题标题】:Workflow for restarting a HTTP server from Clojure REPL从 Clojure REPL 重新启动 HTTP 服务器的工作流程
【发布时间】: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或其他依赖模块时,我必须

  1. 记住不要使用 C-c C-k 重新编译web.clj,因为持有运行实例的原子会从 REPL 中消失(由于来自新编译模块的原子)。

  2. 运行(myproject.web/reinitialize) 会停止服务器然后在重新启动之前重新加载模块。

这样做有两个问题:

  • 我经常忘记第 1 点,然后按C-c C-k。这会导致 REPL 中的服务器 atom 丢失,导致必须终止 swank(或重新启动 emacs),以便我可以在相同的端口号启动服务器。

  • :reload-all 不会像C-c C-k 那样友好地报告编译错误(丑陋的回溯与简洁的可点击错误)。

在这个编辑-编译-重启工作流程中,我怎样才能最好地解决这两个问题?

【问题讨论】:

    标签: clojure workflow read-eval-print-loop


    【解决方案1】:

    你可以替换

    (def server (atom nil))
    

    (defonce server (atom nil))
    

    这样,当您评估缓冲区时,它不会重新定义服务器。

    【讨论】:

      【解决方案2】:

      对于您的第一个问题,您可以将原子存储在不同的命名空间中,并且仅在尚未定义的情况下在加载时覆盖它。将它放在它自己的命名空间中将防止它被 reload-all 删除

      【讨论】:

        猜你喜欢
        • 2015-02-24
        • 2011-12-27
        • 1970-01-01
        • 2011-04-21
        • 2011-04-04
        • 2014-05-09
        • 1970-01-01
        • 2010-12-27
        相关资源
        最近更新 更多