繁体   English   中英

从Clojure REPL重新启动HTTP服务器的工作流程

[英]Workflow for restarting a HTTP server from Clojure REPL

我的一个基于Clojure的项目使用netty( aleph所需)web服务器。 我在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 原子中 ,以便以后可以停止。

我使用Emacs和Swank直接在REPL上启动服务器(在使用Cc Ck编译web.clj之后):

user> (myproject.web/initialize)

每当编辑web.clj或其他相关模块时,我都必须这样做

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

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

这有两个问题:

  • 我经常忘记点#1然后按Cc Ck 这导致REPL中服务器原子丢失,导致必须杀死swank(或重启emacs),以便我可以在相同的端口号启动服务器。

  • :reload-all不会将编译错误报告为与Cc Ck一样友好(丑陋的回溯与简明的可点击错误)。

如何在编辑 - 编译 - 重启工作流程中最好地解决这两个问题?

你可以替换

(def server (atom nil))

(defonce server (atom nil))

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

对于您的第一个问题,您可以将原子存储在不同的命名空间中,并且在加载时仅覆盖它(如果尚未定义)。 把它放在它自己的namepspace中会阻止它被reload-all擦除

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM