Simplify MongoDB code by just storing whole state
- Every time it receives a state, it blows away the existing one and puts in the new one. - There's a non-zero probability of losing the entire state if the server fails after blowing away the previous state and before inserting the new.
This commit is contained in:
parent
48ba2c5449
commit
86bfdf80e4
4 changed files with 21 additions and 51 deletions
|
@ -73,14 +73,14 @@
|
|||
(reset! index-page prod-index-page)
|
||||
(let [to-db (chan)]
|
||||
(db/connect-production-database to-db mongo-url)
|
||||
(state/init-server to-db (db/get-current-grubs) (db/get-current-recipes))
|
||||
(state/init-server to-db (db/get-current-state))
|
||||
(println "Starting production server on localhost:" port)
|
||||
(start-server port)))
|
||||
|
||||
(defn start-development-server [{:keys [port]}]
|
||||
(let [to-db (chan)]
|
||||
(db/connect-development-database to-db)
|
||||
(state/init-server to-db (db/get-current-grubs) (db/get-current-recipes))
|
||||
(state/init-server to-db (db/get-current-state))
|
||||
(println "Starting development server on localhost:" port)
|
||||
(start-server port)))
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
(ns grub.db
|
||||
(:require [grub.util :as util]
|
||||
[grub.sync :as sync]
|
||||
[monger.core :as m]
|
||||
[monger.collection :as mc]
|
||||
[monger.operators :as mo]
|
||||
|
@ -7,54 +8,22 @@
|
|||
|
||||
(def conn (atom nil))
|
||||
(def db (atom nil))
|
||||
(def grub-collection "grubs")
|
||||
(def recipe-collection "recipes")
|
||||
(def collection "grub-lists")
|
||||
(def production-db "grub")
|
||||
(def development-db "grub-dev")
|
||||
|
||||
(defn clear-grubs []
|
||||
(mc/drop @db grub-collection))
|
||||
|
||||
(defn clear-recipes []
|
||||
(mc/drop @db recipe-collection))
|
||||
|
||||
(defn clear-all []
|
||||
(clear-grubs)
|
||||
(clear-recipes))
|
||||
(mc/drop @db collection))
|
||||
|
||||
(defn update-db! [{:keys [grubs recipes]}]
|
||||
(let [deleted-grubs (:deleted grubs)
|
||||
updated-grubs (->> (:updated grubs)
|
||||
(seq)
|
||||
(map (fn [[k v]]
|
||||
(-> v
|
||||
(dissoc :id)
|
||||
(assoc :_id k)))))
|
||||
deleted-recipes (:deleted recipes)
|
||||
updated-recipes (->> (:updated recipes)
|
||||
(seq)
|
||||
(map (fn [[k v]]
|
||||
(-> v
|
||||
(dissoc :id)
|
||||
(assoc :_id k)))))]
|
||||
(doseq [g deleted-grubs]
|
||||
(mc/remove-by-id @db grub-collection g))
|
||||
(doseq [g updated-grubs]
|
||||
(mc/update-by-id @db grub-collection (:_id g) g {:upsert true}))
|
||||
(doseq [r deleted-recipes]
|
||||
(mc/remove-by-id @db recipe-collection r))
|
||||
(doseq [r updated-recipes]
|
||||
(mc/update-by-id @db recipe-collection (:_id r) r {:upsert true}))))
|
||||
(defn update-db! [state]
|
||||
(mc/drop @db collection)
|
||||
(mc/insert @db collection state))
|
||||
|
||||
(defn get-current-grubs []
|
||||
(->> (mc/find-maps @db grub-collection)
|
||||
(sort-by :_id)
|
||||
(map #(clojure.set/rename-keys % {:_id :id}))))
|
||||
|
||||
(defn get-current-recipes []
|
||||
(->> (mc/find-maps @db recipe-collection)
|
||||
(sort-by :_id)
|
||||
(map #(clojure.set/rename-keys % {:_id :id}))))
|
||||
(defn get-current-state []
|
||||
(let [state (first (mc/find-maps @db collection))]
|
||||
(if state
|
||||
(dissoc state :_id)
|
||||
sync/empty-state)))
|
||||
|
||||
(defn connect! [db-name mongo-url]
|
||||
(if mongo-url
|
||||
|
@ -65,8 +34,9 @@
|
|||
|
||||
(defn connect-and-handle-events [to-db db-name & [mongo-url]]
|
||||
(a/go-loop []
|
||||
(if-let [diff (<! to-db)]
|
||||
(do (update-db! diff)
|
||||
(if-let [state (<! to-db)]
|
||||
(do (println "DB got new state")
|
||||
(update-db! state)
|
||||
(recur))
|
||||
(println "Database disconnected")))
|
||||
(let [_conn (connect! db-name mongo-url)]
|
||||
|
|
|
@ -65,7 +65,6 @@
|
|||
(def states (atom []))
|
||||
(def empty-state sync/empty-state)
|
||||
|
||||
;; TODO: Remove watch, close up channels properly
|
||||
#+clj
|
||||
(defn sync-new-client! [>client <client]
|
||||
(let [client-id (java.util.UUID/randomUUID)
|
||||
|
@ -85,8 +84,9 @@
|
|||
(a/close! state-change-events)))))
|
||||
(make-server-agent client-events >client states)))
|
||||
|
||||
(defn init-server [to-db grubs recipes]
|
||||
(reset! states (sync/initial-state grubs recipes))
|
||||
#+clj
|
||||
(defn init-server [to-db initial-state]
|
||||
(reset! states (sync/new-state initial-state))
|
||||
(add-watch states :to-db (fn [_ _ old-states new-states]
|
||||
(a/put! to-db (sync/get-current-state new-states)))))
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
(doseq [grub grubs]
|
||||
(test/is (taxi/find-element driver {:value grub})
|
||||
"Previously added grubs should be loaded on refresh")))
|
||||
(db/clear-grubs))
|
||||
(db/clear-all))
|
||||
|
||||
(defn test-added-grubs-sync [url driver1 driver2]
|
||||
(taxi/to driver1 url)
|
||||
|
@ -75,7 +75,7 @@
|
|||
(defn start-db-and-websocket-server! []
|
||||
(let [to-db (chan)]
|
||||
(db/connect-and-handle-events to-db "grub-integration-test")
|
||||
(state/init-server to-db (db/get-current-grubs) (db/get-current-recipes))))
|
||||
(state/init-server to-db (db/get-current-state))))
|
||||
|
||||
(defn run []
|
||||
(println "Starting integration test")
|
||||
|
|
Loading…
Reference in a new issue