简体   繁体   English

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

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

A Clojure-based project of mine uses the netty (required by aleph ) web server. 我的一个基于Clojure的项目使用netty( aleph所需)web服务器。 I start the server, along with other components, in a web.clj file like this: 我在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))

The server instance is stored in a Clojure atom , so that it can be stopped later. 服务器实例存储在Clojure 原子中 ,以便以后可以停止。

I use Emacs and Swank to directly launch the server on the REPL like this (after compiling web.clj with Cc Ck ): 我使用Emacs和Swank直接在REPL上启动服务器(在使用Cc Ck编译web.clj之后):

user> (myproject.web/initialize)

Whenever web.clj or other dependent modules are edited, I must 每当编辑web.clj或其他相关模块时,我都必须这样做

  1. remember NOT to recompile web.clj using Cc Ck because the atom holding the running instance would vanish (due to the atom from a newly compiled module) from the REPL. 记住不要使用Cc Ck重新编译web.clj因为持有运行实例的原子会从REPL中消失(由于来自新编译模块的原子)。

  2. Run (myproject.web/reinitialize) which stops the server and then reloads the module before starting it again. 运行(myproject.web/reinitialize) ,它会停止服务器,然后在重新启动之前重新加载模块。

There are two problems with this: 这有两个问题:

  • Often I forget point #1 and press Cc Ck anyway. 我经常忘记点#1然后按Cc Ck This causes the loss of server atom in REPL, leading to having to kill swank (or restart emacs) so that I can start the server at the same port number. 这导致REPL中服务器原子丢失,导致必须杀死swank(或重启emacs),以便我可以在相同的端口号启动服务器。

  • :reload-all doesn't report compile errors as friendly as Cc Ck (ugly traceback vs concise clickable errors). :reload-all不会将编译错误报告为与Cc Ck一样友好(丑陋的回溯与简明的可点击错误)。

How can I best address these two problems in this edit-compile-restart workflow? 如何在编辑 - 编译 - 重启工作流程中最好地解决这两个问题?

You can replace 你可以替换

(def server (atom nil))

with

(defonce server (atom nil))

that way when you evaluate the buffer it will not redefine server. 这样,当您评估缓冲区时,它将不会重新定义服务器。

for your first problem you can store the atom in a different namespace and on load only overwrite it if it is not yet defined. 对于您的第一个问题,您可以将原子存储在不同的命名空间中,并且在加载时仅覆盖它(如果尚未定义)。 putting it in it's own namepspace will prevent it from being erased by the reload-all 把它放在它自己的namepspace中会阻止它被reload-all擦除

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

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