diff --git a/src/ring/server/standalone.clj b/src/ring/server/standalone.clj index 0d2a3df..1d940df 100644 --- a/src/ring/server/standalone.clj +++ b/src/ring/server/standalone.clj @@ -12,18 +12,28 @@ (try-port port run-server) (throw ex)))))) -(defn- setup-callbacks [{:keys [init destroy]}] - (if init (init)) - (if destroy - (. (Runtime/getRuntime) - (addShutdownHook (Thread. destroy))))) +(defmacro ^:private in-thread [& body] + `(doto (Thread. (fn [] ~@body)) + (.start))) + +(defn- run-server [server destroy] + (in-thread + (try (.join server) + (finally (if destroy (destroy)))))) (defn serve "Start a web server to run a handler." - [handler & [{:as options}]] - (setup-callbacks options) - (try-port (port options) - (fn [port] - (run-jetty - handler - (merge {:port port} options))))) + [handler & [{:keys [init destroy join?] :as options}]] + (let [options (assoc options :join? false) + destroy (if destroy (memoize destroy))] + (if init (init)) + (if destroy + (. (Runtime/getRuntime) + (addShutdownHook (Thread. destroy)))) + (try-port (port options) + (fn [port] + (let [options (merge {:port port} options) + server (run-jetty handler options) + thread (run-server server destroy)] + (if join? (.join thread)) + server))))) diff --git a/test/ring/server/test/standalone.clj b/test/ring/server/test/standalone.clj index 4a776b9..dbd9975 100644 --- a/test/ring/server/test/standalone.clj +++ b/test/ring/server/test/standalone.clj @@ -43,4 +43,11 @@ (testing ":init option" (let [ran-init? (atom false)] (with-server (test-server {:init #(reset! ran-init? true)}) - (is @ran-init?))))) + (is @ran-init?)))) + + (testing ":destroy option" + (let [ran-destroy? (atom false)] + (with-server (test-server {:destroy #(reset! ran-destroy? true)}) + (is (not @ran-destroy?))) + (Thread/sleep 100) + (is @ran-destroy?))))