Separate server and command line options
This commit is contained in:
parent
b31489b2b8
commit
928baf1439
2 changed files with 118 additions and 116 deletions
|
@ -1,118 +1,9 @@
|
|||
(ns grub.core
|
||||
(:gen-class)
|
||||
(:require [grub.websocket :as ws]
|
||||
[grub.db :as db]
|
||||
[grub.server-sync :as sync]
|
||||
(:require [grub.server :as server]
|
||||
[grub.test.e2e.sync :as e2e]
|
||||
[ring.middleware.resource :as resource]
|
||||
[ring.middleware.content-type :as content-type]
|
||||
[ring.util.response :as resp]
|
||||
[org.httpkit.server :as httpkit]
|
||||
[clojure.core.async :as a :refer [<! >! chan go]]
|
||||
[hiccup.page :as hiccup]
|
||||
[clojure.tools.cli :as cli]))
|
||||
|
||||
(def prod-index-page
|
||||
(hiccup/html5
|
||||
[:head
|
||||
[:title "Grub"]
|
||||
[:meta {:name "viewport" :content "width=device-width, initial-scale=1.0"}]
|
||||
(hiccup/include-css "./css/bootstrap.min.css")
|
||||
(hiccup/include-css "./css/styles.css")]
|
||||
[:body
|
||||
[:div#container]
|
||||
(hiccup/include-js "./js/grub.min.js")]))
|
||||
|
||||
(def dev-index-page
|
||||
(hiccup/html5
|
||||
[:head
|
||||
[:title "Grub"]
|
||||
[:meta {:name "viewport" :content "width=device-width, initial-scale=1.0"}]
|
||||
(hiccup/include-css "./css/bootstrap.css")
|
||||
(hiccup/include-css "./css/styles.css")]
|
||||
[:body
|
||||
[:div#container]
|
||||
(hiccup/include-js "./js/out/goog/base.js")
|
||||
(hiccup/include-js "./js/grub.js")
|
||||
[:script {:type "text/javascript"} "goog.require(\"grub.core\")"]]))
|
||||
|
||||
(def prod-system
|
||||
{:index prod-index-page
|
||||
:database-uri (System/getenv "GRUB_DATABASE_URI")
|
||||
:db-conn nil
|
||||
:port 3000
|
||||
:stop-server nil})
|
||||
|
||||
(def dev-system
|
||||
{:index dev-index-page
|
||||
:database-uri (or (System/getenv "GRUB_DATABASE_URI") "datomic:mem://grub")
|
||||
:db-conn nil
|
||||
:port 3000
|
||||
:stop-server nil})
|
||||
|
||||
(defn sync-client-with-db! [ws-channel db-conn db-reports]
|
||||
(let [from-client (chan)
|
||||
to-client (chan)
|
||||
diffs (chan)
|
||||
full-sync-reqs (chan)
|
||||
{:keys [report-queue tap]} (db/report-queue-subscribe db-reports)
|
||||
on-close (fn []
|
||||
(db/report-queue-unsubscribe db-reports tap)
|
||||
(a/close! from-client)
|
||||
(a/close! to-client)
|
||||
(a/close! diffs)
|
||||
(a/close! full-sync-reqs)
|
||||
)]
|
||||
(ws/add-connected-client! ws-channel to-client from-client on-close)
|
||||
(sync/start-sync! to-client diffs full-sync-reqs db-conn report-queue)
|
||||
(go (loop [] (let [event (<! from-client)]
|
||||
(cond
|
||||
(nil? event) nil ;; drop out of loop
|
||||
(= (:type event) :diff) (do (>! diffs event) (recur))
|
||||
(= (:type event) :full-sync-request) (do (>! full-sync-reqs event) (recur))
|
||||
:else (do (println "Unknown event:" event) (recur))))))))
|
||||
|
||||
(defn handle-websocket [handler db-conn db-reports]
|
||||
(fn [{:keys [websocket?] :as request}]
|
||||
(if websocket?
|
||||
(httpkit/with-channel request ws-channel (sync-client-with-db! ws-channel db-conn db-reports))
|
||||
(handler request))))
|
||||
|
||||
(defn handle-root [handler index]
|
||||
(fn [{:keys [uri] :as request}]
|
||||
(if (= uri "/")
|
||||
(resp/response index)
|
||||
(handler request))))
|
||||
|
||||
(defn wrap-bounce-favicon [handler]
|
||||
(fn [req]
|
||||
(if (= [:get "/favicon.ico"] [(:request-method req) (:uri req)])
|
||||
(resp/not-found "")
|
||||
(handler req))))
|
||||
|
||||
(defn make-handler [{:keys [index]} db-conn db-reports]
|
||||
(-> (fn [req] (resp/not-found "Not found"))
|
||||
(resource/wrap-resource "public")
|
||||
(content-type/wrap-content-type)
|
||||
(handle-root index)
|
||||
(handle-websocket db-conn db-reports)
|
||||
(wrap-bounce-favicon)))
|
||||
|
||||
(defn start [{:keys [port database-uri] :as system}]
|
||||
(let [db-conn (db/connect database-uri)
|
||||
db-reports (db/report-queue-channel db-conn)
|
||||
stop-server (httpkit/run-server (make-handler system db-conn db-reports) {:port port})]
|
||||
(println "Started server on localhost:" port)
|
||||
(assoc system
|
||||
:db-conn db-conn
|
||||
:db-reports db-reports
|
||||
:stop-server stop-server)))
|
||||
|
||||
(defn stop [{:keys [db-conn stop-server] :as system}]
|
||||
(stop-server)
|
||||
(db/disconnect db-conn)
|
||||
system)
|
||||
|
||||
(defn usage [options-summary]
|
||||
(->> ["Usage: <executable> [options] action"
|
||||
""
|
||||
|
@ -147,11 +38,11 @@
|
|||
(not= (count arguments) 1) (exit 1 (usage summary))
|
||||
errors (exit 1 (error-msg errors)))
|
||||
(case (first arguments)
|
||||
"development" (start (merge dev-system options))
|
||||
"dev" (start (merge dev-system options))
|
||||
"e2e" (let [system (start (merge dev-system options))]
|
||||
"development" (server/start (merge server/dev-system options))
|
||||
"dev" (server/start (merge server/dev-system options))
|
||||
"e2e" (let [system (server/start (merge server/dev-system options))]
|
||||
(e2e/run-e2e-tests system)
|
||||
(stop system))
|
||||
"production" (start (merge prod-system options))
|
||||
"prod" (start (merge prod-system options))
|
||||
(server/stop system))
|
||||
"production" (server/start (merge server/prod-system options))
|
||||
"prod" (server/start (merge server/prod-system options))
|
||||
(exit 1 (usage summary)))))
|
||||
|
|
111
src/clj/grub/server.clj
Normal file
111
src/clj/grub/server.clj
Normal file
|
@ -0,0 +1,111 @@
|
|||
(ns grub.server
|
||||
(:require [grub.websocket :as ws]
|
||||
[grub.db :as db]
|
||||
[grub.server-sync :as sync]
|
||||
[ring.middleware.resource :as resource]
|
||||
[ring.middleware.content-type :as content-type]
|
||||
[ring.util.response :as resp]
|
||||
[org.httpkit.server :as httpkit]
|
||||
[clojure.core.async :as a :refer [<! >! chan go]]
|
||||
[hiccup.page :as hiccup]))
|
||||
|
||||
(def prod-index-page
|
||||
(hiccup/html5
|
||||
[:head
|
||||
[:title "Grub"]
|
||||
[:meta {:name "viewport" :content "width=device-width, initial-scale=1.0"}]
|
||||
(hiccup/include-css "./css/bootstrap.min.css")
|
||||
(hiccup/include-css "./css/styles.css")]
|
||||
[:body
|
||||
[:div#container]
|
||||
(hiccup/include-js "./js/grub.min.js")]))
|
||||
|
||||
(def dev-index-page
|
||||
(hiccup/html5
|
||||
[:head
|
||||
[:title "Grub"]
|
||||
[:meta {:name "viewport" :content "width=device-width, initial-scale=1.0"}]
|
||||
(hiccup/include-css "./css/bootstrap.css")
|
||||
(hiccup/include-css "./css/styles.css")]
|
||||
[:body
|
||||
[:div#container]
|
||||
(hiccup/include-js "./js/out/goog/base.js")
|
||||
(hiccup/include-js "./js/grub.js")
|
||||
[:script {:type "text/javascript"} "goog.require(\"grub.core\")"]]))
|
||||
|
||||
(def prod-system
|
||||
{:index prod-index-page
|
||||
:database-uri (System/getenv "GRUB_DATABASE_URI")
|
||||
:db-conn nil
|
||||
:port 3000
|
||||
:stop-server nil})
|
||||
|
||||
(def dev-system
|
||||
{:index dev-index-page
|
||||
:database-uri (or (System/getenv "GRUB_DATABASE_URI") "datomic:mem://grub")
|
||||
:db-conn nil
|
||||
:port 3000
|
||||
:stop-server nil})
|
||||
|
||||
(defn sync-client-with-db! [ws-channel db-conn db-reports]
|
||||
(let [from-client (chan)
|
||||
to-client (chan)
|
||||
diffs (chan)
|
||||
full-sync-reqs (chan)
|
||||
{:keys [report-queue tap]} (db/report-queue-subscribe db-reports)
|
||||
on-close (fn []
|
||||
(db/report-queue-unsubscribe db-reports tap)
|
||||
(a/close! from-client)
|
||||
(a/close! to-client)
|
||||
(a/close! diffs)
|
||||
(a/close! full-sync-reqs)
|
||||
)]
|
||||
(ws/add-connected-client! ws-channel to-client from-client on-close)
|
||||
(sync/start-sync! to-client diffs full-sync-reqs db-conn report-queue)
|
||||
(go (loop [] (let [event (<! from-client)]
|
||||
(cond
|
||||
(nil? event) nil ;; drop out of loop
|
||||
(= (:type event) :diff) (do (>! diffs event) (recur))
|
||||
(= (:type event) :full-sync-request) (do (>! full-sync-reqs event) (recur))
|
||||
:else (do (println "Unknown event:" event) (recur))))))))
|
||||
|
||||
(defn handle-websocket [handler db-conn db-reports]
|
||||
(fn [{:keys [websocket?] :as request}]
|
||||
(if websocket?
|
||||
(httpkit/with-channel request ws-channel (sync-client-with-db! ws-channel db-conn db-reports))
|
||||
(handler request))))
|
||||
|
||||
(defn handle-root [handler index]
|
||||
(fn [{:keys [uri] :as request}]
|
||||
(if (= uri "/")
|
||||
(resp/response index)
|
||||
(handler request))))
|
||||
|
||||
(defn wrap-bounce-favicon [handler]
|
||||
(fn [req]
|
||||
(if (= [:get "/favicon.ico"] [(:request-method req) (:uri req)])
|
||||
(resp/not-found "")
|
||||
(handler req))))
|
||||
|
||||
(defn make-handler [{:keys [index]} db-conn db-reports]
|
||||
(-> (fn [req] (resp/not-found "Not found"))
|
||||
(resource/wrap-resource "public")
|
||||
(content-type/wrap-content-type)
|
||||
(handle-root index)
|
||||
(handle-websocket db-conn db-reports)
|
||||
(wrap-bounce-favicon)))
|
||||
|
||||
(defn start [{:keys [port database-uri] :as system}]
|
||||
(let [db-conn (db/connect database-uri)
|
||||
db-reports (db/report-queue-channel db-conn)
|
||||
stop-server (httpkit/run-server (make-handler system db-conn db-reports) {:port port})]
|
||||
(println "Started server on localhost:" port)
|
||||
(assoc system
|
||||
:db-conn db-conn
|
||||
:db-reports db-reports
|
||||
:stop-server stop-server)))
|
||||
|
||||
(defn stop [{:keys [db-conn stop-server] :as system}]
|
||||
(stop-server)
|
||||
(db/disconnect db-conn)
|
||||
system)
|
Loading…
Reference in a new issue