2011-09-29 15 views
5

Un proyecto mío basado en Clojure utiliza el servidor web netty (requerido por aleph). Empiezo el servidor, junto con otros componentes, en un archivo así:Flujo de trabajo para reiniciar un servidor HTTP de Clojure REPL

(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)) 

La instancia del servidor se almacena en un átomo de Clojure , de modo que pueda ser detenido más tarde.

utilizo Emacs and Swank para iniciar directamente el servidor en el REPL como esto (después de compilar con C-c C-k):

user> (myproject.web/initialize) 

Siempre que se editan u otros módulos dependientes, debo

  1. recuerde NO recompilar utilizando Cc Ck porque el átomo que contiene la instancia en ejecución se desvanecería (debido al átomo de un módulo recién compilado) de REPL.

  2. Ejecute (myproject.web/reinitialize) que detiene el servidor y luego vuelve a cargar el módulo antes de volver a iniciarlo.

Hay dos problemas con este:

  • A menudo se me olvida el punto # 1 y pulse C-c C-k de todos modos. Esto causa la pérdida del átomo del servidor en REPL, lo que lleva a tener que matar swank (o reiniciar emacs) para que pueda iniciar el servidor en el mismo número de puerto.

  • :reload-all no informa errores de compilación tan amigables como C-c C-k (feo rastreo vs errores concisos y seleccionables).

¿Cómo puedo solucionar estos dos problemas en este flujo de trabajo de edición-compilación-reinicio?

Respuesta

6

Puede reemplazar

(def server (atom nil)) 

con

(defonce server (atom nil)) 

de esa manera cuando se evalúa el buffer no redefinirá servidor.

2

para su primer problema puede almacenar el átomo en un espacio de nombre diferente y en la carga solo sobrescribirlo si aún no está definido. poniéndolo en su propio namepspace evitará que se eliminen por la recarga, todo