move refresh queue array object into view-system atom

also means the size is now configured via init! and not an environment
variable
This commit is contained in:
Gered 2016-05-21 19:12:34 -04:00
parent 36f3bdfc64
commit 943a99717f

View file

@ -4,12 +4,14 @@
(:require (:require
[views.protocols :refer [IView id data relevant?]] [views.protocols :refer [IView id data relevant?]]
[plumbing.core :refer [swap-pair!]] [plumbing.core :refer [swap-pair!]]
[clojure.tools.logging :refer [info debug error trace]] [clojure.tools.logging :refer [info debug error trace]]))
[environ.core :refer [env]]))
;; The view-system data structure has this shape: ;; The view-system data structure has this shape:
;; ;;
;; {:views {:id1 view1, id2 view2, ...} ;; {
;;
;; :refresh-queue (ArrayBlockingQueue.)
;; :views {:id1 view1, id2 view2, ...}
;; :send-fn (fn [subscriber-key data] ...) ;; :send-fn (fn [subscriber-key data] ...)
;; :put-hints-fn (fn [hints] ... ) ;; :put-hints-fn (fn [hints] ... )
;; :auth-fn (fn [view-sig subscriber-key context] ...) ;; :auth-fn (fn [view-sig subscriber-key context] ...)
@ -28,10 +30,6 @@
(defonce statistics (atom {})) (defonce statistics (atom {}))
(def refresh-queue-size
(if-let [n (:views-refresh-queue-size env)]
(Long/parseLong n)
1000))
(defn reset-stats! (defn reset-stats!
@ -45,8 +43,6 @@
[] []
(boolean (:logger @statistics))) (boolean (:logger @statistics)))
(def refresh-queue (ArrayBlockingQueue. refresh-queue-size))
(defn ->view-sig (defn ->view-sig
[namespace view-id parameters] [namespace view-id parameters]
{:namespace namespace {:namespace namespace
@ -178,17 +174,18 @@
only if the provided collection of hints is relevant to that view." only if the provided collection of hints is relevant to that view."
[hints {:keys [namespace view-id parameters] :as view-sig}] [hints {:keys [namespace view-id parameters] :as view-sig}]
(let [v (get-in @view-system [:views view-id])] (let [v (get-in @view-system [:views view-id])]
(if-let [^ArrayBlockingQueue refresh-queue (:refresh-queue @view-system)]
(try (try
(if (relevant? v namespace parameters hints) (if (relevant? v namespace parameters hints)
(if-not (.contains ^ArrayBlockingQueue refresh-queue view-sig) (if-not (.contains refresh-queue view-sig)
(when-not (.offer ^ArrayBlockingQueue refresh-queue view-sig) (when-not (.offer refresh-queue view-sig)
(when (collect-stats?) (swap! statistics update-in [:dropped] inc)) (when (collect-stats?) (swap! statistics update-in [:dropped] inc))
(error "refresh-queue full, dropping refresh request for" view-sig)) (error "refresh-queue full, dropping refresh request for" view-sig))
(do (do
(when (collect-stats?) (swap! statistics update-in [:deduplicated] inc)) (when (collect-stats?) (swap! statistics update-in [:deduplicated] inc))
(trace "already queued for refresh" view-sig)))) (trace "already queued for refresh" view-sig))))
(catch Exception e (error "error determining if view is relevant, view-id:" (catch Exception e (error "error determining if view is relevant, view-id:"
view-id "e:" e))))) view-id "e:" e))))))
(defn subscribed-views (defn subscribed-views
"Returns a list of all views in the system that have subscribers." "Returns a list of all views in the system that have subscribers."
@ -231,9 +228,10 @@
refresh requests and when there is one, handles it by running the view, getting the view refresh requests and when there is one, handles it by running the view, getting the view
data and then sending it out to all the view's subscribers. " data and then sending it out to all the view's subscribers. "
[] []
(let [^ArrayBlockingQueue refresh-queue (:refresh-queue @view-system)]
(fn [] (fn []
(try (try
(when-let [{:keys [namespace view-id parameters] :as view-sig} (.poll ^ArrayBlockingQueue refresh-queue 60 TimeUnit/SECONDS)] (when-let [{:keys [namespace view-id parameters] :as view-sig} (.poll refresh-queue 60 TimeUnit/SECONDS)]
(trace "worker running refresh for" view-sig) (trace "worker running refresh for" view-sig)
(if (collect-stats?) (swap! statistics update-in [:refreshes] inc)) (if (collect-stats?) (swap! statistics update-in [:refreshes] inc))
(try (try
@ -250,7 +248,7 @@
(catch InterruptedException e)) (catch InterruptedException e))
(if-not (:stop-workers? @view-system) (if-not (:stop-workers? @view-system)
(recur) (recur)
(trace "exiting worker thread")))) (trace "exiting worker thread")))))
(defn refresh-watcher-thread (defn refresh-watcher-thread
"Returns a refresh watcher thread function. A 'refresh watcher' continually attempts "Returns a refresh watcher thread function. A 'refresh watcher' continually attempts
@ -381,6 +379,11 @@
(def default-options (def default-options
"Default options used to initialize the views system via init!" "Default options used to initialize the views system via init!"
{ {
; the size of the queue used to hold view refresh requests for
; the worker threads. for very heavy systems, this can be set
; higher if you start to get warnings about dropped refresh requests
:refresh-queue-size 1000
; interval in milliseconds at which the refresh watcher thread will ; interval in milliseconds at which the refresh watcher thread will
; check for any queued up hints and dispatch relevant view refresh ; check for any queued up hints and dispatch relevant view refresh
; updates to the worker threads. ; updates to the worker threads.
@ -426,7 +429,8 @@
(let [options (merge default-options options)] (let [options (merge default-options options)]
(trace "initializing views system using options:" options) (trace "initializing views system using options:" options)
(reset! view-system (reset! view-system
{:views (into {} (get-views-map views)) {:refresh-queue (ArrayBlockingQueue. (:refresh-queue-size options))
:views (into {} (get-views-map views))
:send-fn send-fn :send-fn send-fn
:put-hints-fn (:put-hints-fn options) :put-hints-fn (:put-hints-fn options)
:auth-fn (:auth-fn options) :auth-fn (:auth-fn options)