Possible changes - wip
This commit is contained in:
parent
31b6d40aef
commit
3760fc8059
1 changed files with 31 additions and 50 deletions
|
@ -5,61 +5,42 @@
|
||||||
[clojure.core.async :as a :refer [<! >! chan go]]))
|
[clojure.core.async :as a :refer [<! >! chan go]]))
|
||||||
|
|
||||||
;; Server state
|
;; Server state
|
||||||
(def states (ref []))
|
(def states (atom []))
|
||||||
(def to-db (atom nil))
|
|
||||||
|
|
||||||
(defmulti handle-message (fn [msg states client-state] (:type msg)))
|
(defn make-client-agent [in >client]
|
||||||
|
(a/go-loop [client-state sync/empty-state]
|
||||||
(defn full-sync! [msg states client-state]
|
(when-let [msg (<! in)]
|
||||||
(let [new-client (dosync (let [state (sync/get-current-state @states)]
|
(condp = (:type msg)
|
||||||
(ref-set client-state state)))]
|
:diff
|
||||||
(println "full-sync!")
|
(let [{:keys [new-states new-shadow full-sync?]} (sync/apply-diff @states (:diff msg) (:shadow-hash msg))]
|
||||||
(message/full-sync new-client)))
|
(if full-sync?
|
||||||
|
(let [state (get-current-state states)]
|
||||||
(defmethod handle-message :full-sync [msg states client-state]
|
(>! >client message/full-sync state)
|
||||||
(full-sync! msg states client-state))
|
(recur state))
|
||||||
|
(do (reset! states new-states)
|
||||||
(defmethod handle-message :new-state [msg states client-state]
|
(recur new-shadow))))
|
||||||
(let [diff-result (sync/diff-states (:new-states msg) @client-state)
|
:full-sync
|
||||||
{:keys [diff shadow-hash]} diff-result]
|
(let [state (get-current-state @states)]
|
||||||
(println "new-state!")
|
(>! >client message/full-sync state)
|
||||||
(message/diff-msg diff shadow-hash)))
|
(recur state))
|
||||||
|
:new-state
|
||||||
(defmethod handle-message :diff [msg states client-state]
|
(let [{:keys [diff shadow-hash]} (sync/diff-states (:new-states msg) @client-state)]
|
||||||
(dosync
|
(println "new-state!")
|
||||||
(println "diff!")
|
(>! >client (message/diff-msg diff shadow-hash)))
|
||||||
(let [{:keys [diff shadow-hash]} msg
|
(do (println "Unknown event")
|
||||||
apply-result (sync/apply-diff @states diff shadow-hash)
|
(recur client-state))))))
|
||||||
{:keys [new-states new-shadow full-sync?]} apply-result]
|
|
||||||
(ref-set states new-states)
|
|
||||||
(ref-set client-state new-shadow)
|
|
||||||
(when full-sync? (full-sync! msg states client-state)))))
|
|
||||||
|
|
||||||
(defn make-client-agent [in initial-states]
|
|
||||||
(let [out (chan)]
|
|
||||||
(a/go-loop [client-state sync/empty-state
|
|
||||||
states initial-states]
|
|
||||||
(if-let [msg (<! in)]
|
|
||||||
(do (when-let [{:keys [new-client new-states]} (handle-message msg states client-state)]
|
|
||||||
(>! >client response))
|
|
||||||
(recur))
|
|
||||||
(remove-watch states client-id)))
|
|
||||||
out))
|
|
||||||
|
|
||||||
|
;; TODO: Remove watch, close up channels properly
|
||||||
(defn sync-new-client! [>client <client]
|
(defn sync-new-client! [>client <client]
|
||||||
(let [client-id (java.util.UUID/randomUUID)
|
(let [client-id (java.util.UUID/randomUUID)
|
||||||
state-changes (chan)
|
state-changes (chan)
|
||||||
state-change-events (a/map< (fn [s] {:type :new-state :new-states s}) state-changes)
|
state-change-events (a/map< (fn [s] {:type :new-state :new-states s}) state-changes)
|
||||||
events (chan)
|
client-events (chan)]
|
||||||
client-state (ref sync/empty-state)]
|
|
||||||
(add-watch states client-id (fn [_ _ _ new-states] (a/put! state-changes new-states)))
|
(add-watch states client-id (fn [_ _ _ new-states] (a/put! state-changes new-states)))
|
||||||
(a/pipe (a/merge [<client state-change-events]) events)
|
(a/pipe (a/merge [<client state-change-events]) client-events)
|
||||||
(a/go-loop [] (if-let [msg (<! in)]
|
(make-client-agent client-events >client)))
|
||||||
(do (when-let [response (handle-message msg states client-state)]
|
|
||||||
(>! >client response))
|
|
||||||
(recur))
|
|
||||||
(remove-watch states client-id)))))
|
|
||||||
|
|
||||||
(defn init [_to-db grubs recipes]
|
(defn init [to-db grubs recipes]
|
||||||
(dosync (ref-set states (sync/initial-state grubs recipes)))
|
(reset! states (sync/initial-state grubs recipes))
|
||||||
(reset! to-db _to-db))
|
(add-watch states :to-db (fn [_ _ old-states new-states]
|
||||||
|
(a/put! to-db (sync/get-current-state new-states)))))
|
||||||
|
|
Loading…
Reference in a new issue