Рабочий процесс для перезапуска HTTP-сервера из Clojure REPL - PullRequest
5 голосов
/ 30 сентября 2011

Мой проект на основе 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 и Swank , чтобы напрямую запустить сервер на REPL, как это (после компиляции web.clj с C-c C-k):

user> (myproject.web/initialize)

Всякий раз, когда редактируется web.clj или другие зависимые модули, я должен

  1. помнить НЕ перекомпилировать web.clj, используя Cc Ck, потому что атом, содержащий запущенный экземпляр, исчезнет (из-за атома изВновь скомпилированный модуль) из REPL.

  2. Запустите (myproject.web/reinitialize), который останавливает сервер , а затем перезагружает модуль перед его повторным запуском.

Есть две проблемы с этим:

  • Часто я забываю пункт # 1 и в любом случае нажимаю C-c C-k.Это приводит к потере атома сервера в REPL, что приводит к необходимости уничтожить swank (или перезапустить emacs), чтобы я мог запустить сервер с тем же номером порта.

  • :reload-all hasnне сообщают об ошибках компиляции так же дружелюбно, как C-c C-k (некрасивый откат против кратких щелкающих ошибок).

Как лучше всего решить эти две проблемы в этом рабочем процессе edit-compile-restart?

Ответы [ 2 ]

6 голосов
/ 30 сентября 2011

Вы можете заменить

(def server (atom nil))

с

(defonce server (atom nil))

таким образом, при оценке буфера он не будет переопределять сервер.

2 голосов
/ 30 сентября 2011

для вашей первой проблемы вы можете сохранить атом в другом пространстве имен и при загрузке перезаписать его, только если он еще не определен.размещение его в собственном пространстве имен предотвратит его стирание с помощью reload-all

...