From 86bfdf80e4b60dd3792c3e9a59b16cdf6153be4c Mon Sep 17 00:00:00 2001 From: Nicholas Kariniemi Date: Sat, 4 Oct 2014 23:20:55 +0300 Subject: [PATCH] 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. --- src/clj/grub/core.clj | 4 +- src/clj/grub/db.clj | 58 ++++++------------------- src/cljx/grub/state.cljx | 6 +-- src/test/grub/test/integration/core.clj | 4 +- 4 files changed, 21 insertions(+), 51 deletions(-) diff --git a/src/clj/grub/core.clj b/src/clj/grub/core.clj index fedd41c..f6a9665 100644 --- a/src/clj/grub/core.clj +++ b/src/clj/grub/core.clj @@ -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))) diff --git a/src/clj/grub/db.clj b/src/clj/grub/db.clj index 90cdac5..30765d5 100644 --- a/src/clj/grub/db.clj +++ b/src/clj/grub/db.clj @@ -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 (client 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))))) diff --git a/src/test/grub/test/integration/core.clj b/src/test/grub/test/integration/core.clj index cc12d05..3916f34 100644 --- a/src/test/grub/test/integration/core.clj +++ b/src/test/grub/test/integration/core.clj @@ -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")