[英]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
或其他相关模块时,我都必须这样做
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中消失(由于来自新编译模块的原子)。
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.