¿Cuál es la mejor manera de insertar un nuevo código en un servidor de anillo de producción sin reiniciar toda la JVM?Código de recarga en un servidor ring-clojure de producción
Actualmente utilizo wrap-reload en producción, pero esto no funciona para mí porque a veces quiero ejecutar comandos en el repl (haciendo migraciones de bases de datos por ejemplo) antes de que ring comience a manejar peticiones con el nuevo código. También hay varios blogs y tutoriales que dicen que no se debe usar wrap-reload en la producción, aunque no entiendo por qué no.
He encontrado la siguiente solución, pero confieso que no entiendo muy bien lo que sucede bajo el capó. Me preguntaba si podría obtener un control de cordura por alguien que lo haga. ¿Esta técnica parece razonable?
La idea es tener una ruta (/ admin/reload-clj) que haga que se vuelva a cargar todo el código de clojure.
(defonce ^:dynamic *jetty*)
(declare reload-clj)
(defn app [req]
...
(when (= (req :uri) "/admin/reload-clj") (reload-clj req))
...)
(defn start-jetty []
(let [j (run-jetty app {:port (http-port) :join? false :max-threads 16})]
(dosync (ref-set *jetty* j))
j))
(defn reload-clj [req]
(future
(log/info "Reloading clojure code...")
(require '(whrusrv admin main utils wdb) :reload-all)
(.stop @*jetty*)
(start-jetty)
(log/info "Clojure reload success!"))
{:status 200
:headers {"Content-Type" "text/plain"}
:body "Reloading..."})
(defn -main [& args]
(start-jetty))
Gracias por la explicación, ¡eso aclara las cosas! –