Refactor - wip
This commit is contained in:
parent
5a66361746
commit
fe5bd00427
2 changed files with 84 additions and 0 deletions
|
@ -5,6 +5,33 @@
|
||||||
[clojure.core.async :as a :refer [<! >! chan go]]
|
[clojure.core.async :as a :refer [<! >! chan go]]
|
||||||
[hasch.core :as hasch]))
|
[hasch.core :as hasch]))
|
||||||
|
|
||||||
|
(def initial-state {:hash (hasch/uuid cs/empty-state)
|
||||||
|
:state cs/empty-state})
|
||||||
|
(def states (atom [initial-state]))
|
||||||
|
|
||||||
|
(defn get-history-state [states hash]
|
||||||
|
(:state (first (filter #(= (:hash %) hash) states))))
|
||||||
|
|
||||||
|
(defn add-history-state [current new-state]
|
||||||
|
(let [{:keys [state hash]} (first current)
|
||||||
|
new-hash (hasch/uuid new-state)]
|
||||||
|
(if (= hash new-hash)
|
||||||
|
current
|
||||||
|
(conj current {:hash hash :state state}))))
|
||||||
|
|
||||||
|
(defn receive-diff [states diff shadow-hash]
|
||||||
|
(let [state (:state (first states))
|
||||||
|
shadow (get-history-state states shadow-hash)]
|
||||||
|
(if shadow
|
||||||
|
{:new-state (diff/patch-state state diff)
|
||||||
|
:new-shadow (diff/patch-state shadow diff)
|
||||||
|
:full-sync? false}
|
||||||
|
{:new-state state
|
||||||
|
:new-shadow state
|
||||||
|
:full-sync? true})))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(def state (atom cs/empty-state))
|
(def state (atom cs/empty-state))
|
||||||
(def to-db (atom nil))
|
(def to-db (atom nil))
|
||||||
(def to-all (chan))
|
(def to-all (chan))
|
||||||
|
@ -26,6 +53,7 @@
|
||||||
{:grubs (util/map-by-key :id grubs)
|
{:grubs (util/map-by-key :id grubs)
|
||||||
:recipes (util/map-by-key :id recipes)})
|
:recipes (util/map-by-key :id recipes)})
|
||||||
|
|
||||||
|
|
||||||
(defn sync-new-client! [to from]
|
(defn sync-new-client! [to from]
|
||||||
(let [client-id (java.util.UUID/randomUUID)
|
(let [client-id (java.util.UUID/randomUUID)
|
||||||
client-state (atom cs/empty-state)
|
client-state (atom cs/empty-state)
|
||||||
|
|
56
src/test/grub/test/unit/state.clj
Normal file
56
src/test/grub/test/unit/state.clj
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
(ns grub.test.unit.state
|
||||||
|
(:require [grub.state :as s]
|
||||||
|
[grub.common-state :as cs]
|
||||||
|
[clojure.test :refer :all]
|
||||||
|
[hasch.core :as hasch]))
|
||||||
|
|
||||||
|
(deftest apply-diff-normally
|
||||||
|
;; Apply changes and return ACK for in sync client/server
|
||||||
|
(let [state {:grubs {"1" {:text "2 apples" :completed false}}
|
||||||
|
:recipes {}}
|
||||||
|
hash (hasch/uuid state)
|
||||||
|
states [{:hash hash :state state}]
|
||||||
|
diff {:grubs {:updated {"1" {:completed true}} :deleted #{}}}
|
||||||
|
shadow-hash hash
|
||||||
|
{:keys [new-state new-shadow full-sync?]} (s/receive-diff states diff shadow-hash)]
|
||||||
|
(do
|
||||||
|
(is (= {:grubs {"1" {:text "2 apples" :completed true}}
|
||||||
|
:recipes {}}
|
||||||
|
new-state))
|
||||||
|
(is (= {:grubs {"1" {:text "2 apples" :completed true}}
|
||||||
|
:recipes {}}
|
||||||
|
new-shadow))
|
||||||
|
(is (not full-sync?)))))
|
||||||
|
|
||||||
|
(deftest server-state-changed
|
||||||
|
;; Send differences back if server state changed
|
||||||
|
(let [state {:grubs {"1" {:text "3 apples" :completed false}} :recipes {}}
|
||||||
|
prev {:grubs {"1" {:text "2 apples" :completed false}} :recipes {}}
|
||||||
|
states [{:hash (hasch/uuid state) :state state}
|
||||||
|
{:hash (hasch/uuid prev) :state prev}]
|
||||||
|
diff {:grubs {:updated {"1" {:completed true}} :deleted #{}}}
|
||||||
|
shadow-hash (hasch/uuid prev)
|
||||||
|
{:keys [new-state new-shadow full-sync?]} (s/receive-diff states diff shadow-hash)]
|
||||||
|
(do
|
||||||
|
(is (= {:grubs {"1" {:text "3 apples" :completed true}}
|
||||||
|
:recipes {}}
|
||||||
|
new-state))
|
||||||
|
(is (= {:grubs {"1" {:text "2 apples" :completed true}}
|
||||||
|
:recipes {}}
|
||||||
|
new-shadow))
|
||||||
|
(is (not full-sync?)))))
|
||||||
|
|
||||||
|
(deftest full-sync-if-client-too-far-out-of-sync
|
||||||
|
;; Shadow hash not in history means client has fallen too far
|
||||||
|
;; out of sync. Send a full sync
|
||||||
|
(let [state {:grubs {"1" {:text "2 apples" :completed false}} :recipes {}}
|
||||||
|
prev {:grubs {"1" {:text "2 apples" :completed false}} :recipes {}}
|
||||||
|
states [{:hash (hasch/uuid state) :state state}
|
||||||
|
{:hash (hasch/uuid prev) :state prev}]
|
||||||
|
shadow-hash (hasch/uuid {:grubs {} :recipes {}})
|
||||||
|
diff {:grubs {:updated {"1" {:completed true}} :deleted #{}}}
|
||||||
|
{:keys [new-state new-shadow full-sync?]} (s/receive-diff states diff shadow-hash)]
|
||||||
|
(do
|
||||||
|
(is (= state new-state))
|
||||||
|
(is (= state new-shadow))
|
||||||
|
(is full-sync?))))
|
Loading…
Add table
Reference in a new issue