fully moved subscription persistence into persistor namespace; rearranged subscription fn args; added config

This commit is contained in:
Dave Della Costa 2014-06-10 19:29:44 +09:00
parent 6717ad46db
commit d34e37e4ca
7 changed files with 94 additions and 66 deletions

View file

@ -1,17 +1,12 @@
(ns views.base-subscribed-views
(:require
[views.persistor :refer [subscribe-to-view]]
[views.persistor :refer [subscribe-to-view! unsubscribe-from-view! unsubscribe-from-all-views!]]
[views.subscribed-views :refer [SubscribedViews]]
[views.subscriptions :as vs :refer [add-subscriptions! remove-subscription! subscriptions-for]]
[views.subscriptions :refer [default-ns]]
[views.filters :refer [view-filter]]
[clojure.tools.logging :refer [debug info warn error]]
[clojure.core.async :refer [put! <! go thread]]))
(defmacro config
[{:keys [db schema templates send-fn subscriber-fn namespace-fn unsafe?]}]
`(do (defschema schema db "public")
{:db db :schema schema :subscribed-views (BaseSubscribedViews. db templates send-fn subscriber-fn namespace-fn unsafe?)}))
(defn send-fn*
[send-fn address msg]
(if send-fn
@ -24,7 +19,7 @@
(defn namespace-fn*
[namespace-fn msg]
(if namespace-fn (namespace-fn msg) vs/default-ns))
(if namespace-fn (namespace-fn msg) default-ns))
(deftype BaseSubscribedViews [opts]
SubscribedViews
@ -38,27 +33,26 @@
popts {:templates templates :subscriber-key subscriber-key :namespace namespace}]
(info "Subscribing views: " view-sigs " for subscriber " subscriber-key ", in namespace " namespace)
(when (seq view-sigs)
;; (thread
(thread
(doseq [vs view-sigs]
(send-fn* send-fn subscriber-key (subscribe-to-view persistor db vs popts))))))
(send-fn* send-fn subscriber-key (subscribe-to-view! persistor db vs popts)))))))
(unsubscribe-views
[this msg]
(let [{:keys [subscriber-key-fn namespace-fn]} opts
(let [{:keys [subscriber-key-fn namespace-fn persistor]} opts
subscriber-key (subscriber-key-fn* subscriber-key-fn msg)
namespace (namespace-fn* namespace-fn msg)
view-sigs (:views msg)]
(info "Unsubscribing views: " view-sigs " for subscriber " subscriber-key)
(doseq [vs view-sigs] (remove-subscription! subscriber-key vs namespace))))
(doseq [vs view-sigs] (unsubscribe-from-view! persistor vs subscriber-key namespace))))
(disconnect [this msg]
(let [{:keys [subscriber-key-fn namespace-fn]} opts
(let [{:keys [subscriber-key-fn namespace-fn persistor]} opts
subscriber-key (subscriber-key-fn* subscriber-key-fn msg)
namespace (namespace-fn* namespace-fn msg)
view-sigs (if namespace (subscriptions-for subscriber-key namespace) (subscriptions-for subscriber-key))]
(doseq [vs view-sigs] (remove-subscription! subscriber-key vs namespace))))
namespace (namespace-fn* namespace-fn msg)]
(unsubscribe-from-all-views! persistor subscriber-key namespace)))
;; DB interaction
(subscribed-views [this] ) ;; (vs/compiled-views))
(subscribed-views [this])
(broadcast-deltas [this fdb views-with-deltas]))

9
src/views/core.clj Normal file
View file

@ -0,0 +1,9 @@
(ns views.core
(:require
[views.base-subscribed-views])
(:import
[views.base_subscribed_views BaseSubscribedViews]))
(defmacro config
[{:keys [db schema] :as opts}]
{:db db :schema schema :subscribed-views (BaseSubscribedViews. opts)})

View file

@ -1,16 +1,27 @@
(ns views.persistor
(:require
[clojure.java.jdbc :as j]
[views.subscriptions :refer [add-subscription! compiled-view-for]]
[views.subscriptions :refer [add-subscription! remove-subscription! compiled-view-for subscriptions-for]]
[views.db.load :refer [initial-view]]))
(defprotocol IPersistor
(subscribe-to-view [this db view-sig opts]))
(subscribe-to-view! [this db view-sig opts])
(unsubscribe-from-view! [this view-sig subscriber-key namespace])
(unsubscribe-from-all-views! [this subscriber-key namespace]))
(deftype InMemoryPersistor []
IPersistor
(subscribe-to-view
(subscribe-to-view!
[persistor db view-sig {:keys [templates subscriber-key namespace]}]
(j/with-db-transaction [t db :isolation :serializable]
(add-subscription! subscriber-key view-sig templates namespace)
(initial-view t view-sig templates (:view (compiled-view-for view-sig))))))
(add-subscription! view-sig templates subscriber-key namespace)
(initial-view t view-sig templates (:view (compiled-view-for view-sig)))))
(unsubscribe-from-view!
[this view-sig subscriber-key namespace]
(remove-subscription! view-sig subscriber-key namespace))
(unsubscribe-from-all-views!
[this subscriber-key namespace]
(doseq [vs (subscriptions-for subscriber-key namespace)]
(remove-subscription! vs subscriber-key namespace))))

View file

@ -18,23 +18,23 @@
#{subscriber-key})))
(defn add-subscription*
[subscriber-key view-sig templates namespace]
[view-sig templates subscriber-key namespace]
(fn [svs]
(-> svs
(update-in [namespace view-sig :subscriptions] (add-subscriber-key subscriber-key))
(assoc-in [namespace view-sig :view-data] (vdb/view-map (get-in templates [(first view-sig) :fn]) view-sig)))))
(defn add-subscription!
([subscriber-key view-sig templates]
(add-subscription! subscriber-key view-sig templates default-ns))
([subscriber-key view-sig templates namespace]
(swap! subscribed-views (add-subscription* subscriber-key view-sig templates namespace))))
([view-sig templates subscriber-key]
(add-subscription! view-sig templates subscriber-key default-ns))
([view-sig templates subscriber-key namespace]
(swap! subscribed-views (add-subscription* view-sig templates subscriber-key namespace))))
(defn add-subscriptions!
([subscriber-key view-sigs templates]
(add-subscriptions! subscriber-key view-sigs templates default-ns))
([subscriber-key view-sigs templates namespace]
(mapv #(add-subscription! subscriber-key % templates namespace) view-sigs)))
([view-sigs templates subscriber-key]
(add-subscriptions! view-sigs templates subscriber-key default-ns))
([view-sigs templates subscriber-key namespace]
(mapv #(add-subscription! % templates subscriber-key namespace) view-sigs)))
(defn subscriptions-for
([subscriber-key] (subscriptions-for subscriber-key default-ns))
@ -51,14 +51,14 @@
(get-in @subscribed-views [namespace view-sig :subscriptions])))
(defn subscribed-to?
([subscriber-key view-sig]
(subscribed-to? subscriber-key view-sig default-ns))
([subscriber-key view-sig namespace]
([view-sig subscriber-key]
(subscribed-to? view-sig subscriber-key default-ns))
([view-sig subscriber-key namespace]
(if-let [view-subs (subscribed-to view-sig namespace)]
(view-subs subscriber-key))))
(defn- remove-key-or-view
[subscriber-key view-sig namespace]
[view-sig subscriber-key namespace]
(fn [subbed-views]
(let [path [namespace view-sig :subscriptions]
updated (update-in subbed-views path disj subscriber-key)]
@ -67,11 +67,11 @@
(update-in updated [namespace] dissoc view-sig)))))
(defn remove-subscription!
([subscriber-key view-sig]
(remove-subscription! subscriber-key view-sig default-ns))
([subscriber-key view-sig namespace]
(when (subscribed-to? subscriber-key view-sig namespace)
(swap! subscribed-views (remove-key-or-view subscriber-key view-sig namespace)))))
([view-sig subscriber-key]
(remove-subscription! view-sig subscriber-key default-ns))
([view-sig subscriber-key namespace]
(when (subscribed-to? view-sig subscriber-key namespace)
(swap! subscribed-views (remove-key-or-view view-sig subscriber-key namespace)))))
(defn compiled-view-for
([view-sig] (compiled-view-for view-sig default-ns))

15
test/views/core_test.clj Normal file
View file

@ -0,0 +1,15 @@
(ns views.core-test
(:require
[clojure.test :refer [use-fixtures deftest is]]
[edl.core :refer [defschema]]
[views.fixtures :as vf]
[views.subscribed-views :as vs] ;; :refer [SubscribedViews]]
[views.core :refer [config]]))
(defschema schema vf/db "public")
(deftest configures-views
(let [conf (config {:db vf/db :schema schema :templates vf/templates :unsafe? true})]
(println (satisfies? views.subscribed-views/SubscribedViews (:subscribed-views conf))) ; wtf?!
;; (is (satisfies? views.subscribed-views/SubscribedViews (:subscribed-views conf)))))
))

View file

@ -1,7 +1,6 @@
(ns views.db.core-test
(:require
[clojure.test :refer [deftest is run-tests]]
[edl.core :refer [defschema]]
[honeysql.core :as hsql]
[honeysql.helpers :as hh]
[views.fixtures :as vf]
@ -79,7 +78,7 @@
(let [tmpl (with-meta vf/users-tmpl {:bulk-update? true})]
(is (:bulk-update? (vdb/view-map tmpl [:users])))))
(defschema schema vf/db "public")
;; (defschema schema vf/db "public")
;; (deftest sends-entire-view-on-every-update-with-bulk-update
;; (let [tmpl (with-meta vf/users-tmpl {:bulk-update? true})

View file

@ -13,21 +13,21 @@
(deftest adds-a-subscription
(let [key 1, view-sig [:user-posts 1]]
(vs/add-subscription! key view-sig templates)
(is (vs/subscribed-to? key view-sig))))
(vs/add-subscription! view-sig templates key)
(is (vs/subscribed-to? view-sig key))))
(deftest can-use-namespace
(let [namespace1 1, namespace2 2, key 1, view-sig [:user-posts 1]]
(vs/add-subscription! key view-sig templates namespace1)
(vs/add-subscription! key view-sig templates namespace2)
(is (vs/subscribed-to? key view-sig namespace1))
(is (vs/subscribed-to? key view-sig namespace2))))
(vs/add-subscription! view-sig templates key namespace1)
(vs/add-subscription! view-sig templates key namespace2)
(is (vs/subscribed-to? view-sig key namespace1))
(is (vs/subscribed-to? view-sig key namespace2))))
(deftest removes-a-subscription
(let [key 1, view-sig [:user-posts 1]]
(vs/add-subscription! key view-sig templates)
(vs/remove-subscription! key view-sig)
(is (not (vs/subscribed-to? key view-sig)))))
(vs/add-subscription! view-sig templates key)
(vs/remove-subscription! view-sig key)
(is (not (vs/subscribed-to? view-sig key)))))
(deftest doesnt-fail-or-create-view-entry-when-empty
(vs/remove-subscription! 1 [:user-posts 1])
@ -35,42 +35,42 @@
(deftest removes-a-subscription-with-namespace
(let [namespace1 1, namespace2 2, key 1, view-sig [:user-posts 1]]
(vs/add-subscription! key view-sig templates namespace1)
(vs/add-subscription! key view-sig templates namespace2)
(vs/remove-subscription! key view-sig namespace1)
(is (not (vs/subscribed-to? key view-sig namespace1)))
(is (vs/subscribed-to? key view-sig namespace2))))
(vs/add-subscription! view-sig templates key namespace1)
(vs/add-subscription! view-sig templates key namespace2)
(vs/remove-subscription! view-sig key namespace1)
(is (not (vs/subscribed-to? view-sig key namespace1)))
(is (vs/subscribed-to? view-sig key namespace2))))
(deftest removes-unsubscribed-to-view-from-subscribed-views
(let [key 1, view-sig [:user-posts 1]]
(vs/add-subscription! key view-sig templates)
(vs/remove-subscription! key view-sig)
(vs/add-subscription! view-sig templates key)
(vs/remove-subscription! view-sig key)
(is (= {vs/default-ns {}} @vs/subscribed-views))))
(deftest adds-multiple-views-at-a-time
(let [key 1, view-sigs [[:user-posts 1] [:user-posts 2]]]
(vs/add-subscriptions! key view-sigs templates)
(is (vs/subscribed-to? key (first view-sigs)))
(is (vs/subscribed-to? key (last view-sigs)))))
(vs/add-subscriptions! view-sigs templates key)
(is (vs/subscribed-to? (first view-sigs) key))
(is (vs/subscribed-to? (last view-sigs) key))))
(deftest subscribing-compiles-and-stores-view-maps
(let [key 1, view-sig [:user-posts 1]]
(vs/add-subscription! key view-sig templates)
(vs/add-subscription! view-sig templates key)
(is (= (:view (vs/compiled-view-for [:user-posts 1]))
(user-posts-tmpl 1)))))
(deftest removing-last-view-sub-removes-compiled-view
(let [key 1, view-sig [:user-posts 1]]
(vs/add-subscription! key view-sig templates)
(vs/remove-subscription! key view-sig)
(vs/add-subscription! view-sig templates key)
(vs/remove-subscription! view-sig key)
(is (nil? (vs/compiled-view-for [:user-posts 1])))))
(deftest retrieves-subscriptions-for-subscriber
(let [key 1, view-sigs [[:users][:user-posts 1]]]
(vs/add-subscriptions! key view-sigs templates)
(vs/add-subscriptions! view-sigs templates key)
(is (= (set (vs/subscriptions-for 1)) (set view-sigs)))))
(deftest retrieves-subscriptions-for-subscriber-with-namespace
(let [key 1, view-sigs [[:users][:user-posts 1]] namespace 1]
(vs/add-subscriptions! key view-sigs templates namespace)
(vs/add-subscriptions! view-sigs templates key namespace)
(is (= (set (vs/subscriptions-for 1 namespace)) (set view-sigs)))))