Basic infrastructure working.

This commit is contained in:
Alexander K. Hudek 2015-01-18 18:13:50 -05:00
parent 6d7ae24a3e
commit afb4b91103
4 changed files with 32 additions and 36 deletions

View file

@ -1,6 +1,9 @@
# views
Eventually consistent external materialized views for SQL databases.
Eventually consistent external materialized views.
*Notice: despite being 1.x.x, this is incomplete. Version 2.0.0 will be
the first release version.*
## Design
@ -12,28 +15,11 @@ TODO
## Testing
You will need to set up the test db to run the tests:
```bash
$ psql -Upostgres < test/views/test_db.sql
CREATE ROLE
CREATE DATABASE
$
```
This will create a role `views_user` and a database owned by that user called `views_test`.
(You can change the database settings if you'd like by editing that file and checking the config in `test/views/fixtures.clj`.)
Then, to run all tests:
```bash
$ lein with-profile test test
```
TODO
## License
Copyright © 2014 DiligenceEngine
Copyright © 2015 DiligenceEngine
Authors Dave Della Costa (https://github.com/ddellacosta) and Alexander Hudek (https://github.com/akhudek)

View file

@ -1,5 +1,5 @@
(defproject views "1.0.0"
:description "You underestimate the power of the SQL side"
:description "A view to the past helps navigate the future."
:url "https://github.com/diligenceengine/views"
@ -9,10 +9,7 @@
:dependencies [[org.clojure/clojure "1.6.0"]
[org.clojure/tools.logging "0.2.6"]
[org.clojure/core.async "0.1.303.0-886421-alpha"]
[org.clojure/java.jdbc "0.3.3"]
[honeysql "0.4.3"]
[edl "0.1.0"]
[org.postgresql/postgresql "9.2-1003-jdbc4"]
[clj-logging-config "1.9.10"]
[zip-visit "1.0.2"]
[prismatic/plumbing "0.3.5"]

View file

@ -1,7 +1,8 @@
(ns views.core
(:require
[views.protocols :refer [IView id data relevant?]]
[plumbing.core :refer [swap-pair!]]))
[plumbing.core :refer [swap-pair!]]
[clojure.tools.logging :refer [debug]]))
;; The view-system data structure has this shape:
;;
@ -29,7 +30,7 @@
(if-let [view (get-in @view-system [:views view-id])]
(let [vdata (data view namespace parameters)]
(swap! view-system subscribe-view! [namespace view-id parameters] subscriber-key (hash vdata))
((get @view-system :send-fn) subscriber-key vdata))))
((get @view-system :send-fn) subscriber-key [[view-id parameters] vdata]))))
(defn remove-from-subscribers
[view-system view-sig subscriber-key]
@ -61,7 +62,7 @@
hdata (hash vdata)]
(when-not (= hdata (get-in @view-system [:hashes view-sig]))
(doseq [s (get-in @view-system [:subscribers view-sig])]
((:send-fn @view-system) s vdata))
((:send-fn @view-system) s [[view-id parameters] vdata]))
(swap! view-system assoc-in [:hashes view-sig] hdata))))))
(defn subscribed-views
@ -78,6 +79,7 @@
"Given a collection of hints, find all dirty views."
[view-system]
(let [hints (pop-hints! view-system)]
(debug "refresh hints:" hints)
(mapv #(refresh-view! view-system hints %) (subscribed-views @view-system))
(swap! view-system assoc :last-update (System/currentTimeMillis))))
@ -89,19 +91,30 @@
[last-update min-refresh-interval]
(Thread/sleep (max 0 (- min-refresh-interval (- (System/currentTimeMillis) last-update)))))
(defn start-update-watcher!
(defn update-watcher!
"A single threaded view update mechanism."
[view-system min-refresh-interval]
(swap! view-system assoc :last-update 0)
(.start (Thread. (fn [] (let [last-update (:last-update @view-system)]
(if (can-refresh? last-update min-refresh-interval)
(do (refresh-views! view-system) (recur))
(do (wait last-update min-refresh-interval) (recur))))))))
(refresh-views! view-system)
(wait last-update min-refresh-interval))
(recur))))))
(defn hint
"Create a hint."
[namespace hint]
{:namespace namespace :hint hint})
(defn add-hint!
"Add a hint to the system."
[view-system namespace hint]
(swap! view-system update-in [:hints] (fnil conj #{}) {:namespace namespace :hint hint}))
[view-system hint]
(swap! view-system update-in [:hints] (fnil conj #{}) hint))
(defn add-views!
"Add a collection of views to the system."
[view-system views]
(swap! view-system update-in [:views] (fnil into {}) (map vector (map id views) views)))
(comment
(defrecord SQLView [id query-fn]

View file

@ -1,4 +1,4 @@
(ns views.honey-sql.util
(ns views.honeysql.util
(:require
[honeysql.core :as hsql]
[honeysql.helpers :as hh]