JVM全体を再起動せずに新しいコードをプロダクションリングサーバーにプッシュする最良の方法は何ですか?
現在、本番環境で wrap-reload を使用していますが、リングが新しいコードでリクエストの処理を開始する前に、repl でコマンドを実行したい場合があるため (データベースの移行など)、これはうまくいきません。また、さまざまなブログやチュートリアルで、本番環境で wrap-reload を使用しないようにと書かれていますが、その理由はわかりません。
私は次の解決策を思いつきましたが、内部で何が起こっているのかを深く理解していないことを告白します. 誰かが健全性チェックを受けられるかどうか疑問に思っていました。このテクニックは合理的ですか?
アイデアは、すべての clojure コードをリロードさせるパス (/admin/reload-clj) を持つことです。
(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))