[英]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
或其他相關模塊時,我都必須這樣做
記住不要使用Cc Ck重新編譯web.clj
因為持有運行實例的原子會從REPL中消失(由於來自新編譯模塊的原子)。
運行(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.