Каков наилучший способ отправить новый код на производственный кольцевой сервер без перезапуска всей JVM?
В настоящее время я использую wrap-reload в производственном процессе, но это не совсем подходит для меня, потому что иногда я хочувыполнить команды в repl (например, выполнить миграцию базы данных) до того, как ring начнет обрабатывать запросы с новым кодом.Также в различных блогах и учебных руководствах говорится, что не следует использовать wrap-reload в производстве, хотя я не понимаю, почему нет.
Я пришел к следующему решению, но, признаюсь, у меня нетглубокое понимание того, что происходит под капотом.Мне было интересно, смогу ли я получить проверку вменяемости кем-то, кто делает.Эта техника кажется разумной?
Идея состоит в том, чтобы иметь путь (/ admin / reload-clj), который приводит к перезагрузке всего кода 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))