remove sweeper thread threshold stuff
i'm not totally convinced that it is that useful? i feel like just making the sweeper thread run less frequently would solve most of the same problems that the threshold was (possibly?) intended to solve?
This commit is contained in:
parent
6550dc4450
commit
20b4067188
|
@ -73,7 +73,7 @@
|
||||||
(all-entries [store]
|
(all-entries [store]
|
||||||
"Returns a map containing all entries currently in the session store."))
|
"Returns a map containing all entries currently in the session store."))
|
||||||
|
|
||||||
(defrecord MemoryAgingStore [session-atom thread ttl refresh-on-write refresh-on-read op-counter op-threshold on-removal]
|
(defrecord MemoryAgingStore [session-atom thread ttl refresh-on-write refresh-on-read on-removal]
|
||||||
AgingStore
|
AgingStore
|
||||||
(read-timestamp [_ key]
|
(read-timestamp [_ key]
|
||||||
(get-in @session-atom [key :timestamp]))
|
(get-in @session-atom [key :timestamp]))
|
||||||
|
@ -97,8 +97,6 @@
|
||||||
nil)))))
|
nil)))))
|
||||||
|
|
||||||
(write-session [_ key data]
|
(write-session [_ key data]
|
||||||
(if op-threshold
|
|
||||||
(swap! op-counter inc))
|
|
||||||
(let [key (or key (unique-id))]
|
(let [key (or key (unique-id))]
|
||||||
(if on-removal
|
(if on-removal
|
||||||
; when we have an on-removal listener, we need to check if we are overwriting an entry
|
; when we have an on-removal listener, we need to check if we are overwriting an entry
|
||||||
|
@ -128,13 +126,9 @@
|
||||||
|
|
||||||
(defn- sweeper-thread
|
(defn- sweeper-thread
|
||||||
"Sweeper thread that watches the session and cleans it."
|
"Sweeper thread that watches the session and cleans it."
|
||||||
[session-atom ttl op-counter op-threshold sweep-interval on-removal]
|
[session-atom ttl sweep-interval on-removal]
|
||||||
(loop []
|
(loop []
|
||||||
(let [[old new] (if op-threshold
|
(let [[old new] (swap-vals! session-atom sweep-session ttl)]
|
||||||
(when (>= @op-counter op-threshold)
|
|
||||||
(reset! op-counter 0)
|
|
||||||
(swap-vals! session-atom sweep-session ttl))
|
|
||||||
(swap-vals! session-atom sweep-session ttl))]
|
|
||||||
(if (and on-removal
|
(if (and on-removal
|
||||||
(not= old new))
|
(not= old new))
|
||||||
; TODO: is there a faster way to get the keys difference? maybe this is fine ... ?
|
; TODO: is there a faster way to get the keys difference? maybe this is fine ... ?
|
||||||
|
@ -153,13 +147,12 @@
|
||||||
(def default-opts
|
(def default-opts
|
||||||
{:refresh-on-write true
|
{:refresh-on-write true
|
||||||
:refresh-on-read true
|
:refresh-on-read true
|
||||||
:sweep-threshold nil
|
|
||||||
:sweep-interval 30})
|
:sweep-interval 30})
|
||||||
|
|
||||||
(defn aging-memory-store
|
(defn aging-memory-store
|
||||||
"Creates an in-memory session storage engine where entries expire after the given ttl"
|
"Creates an in-memory session storage engine where entries expire after the given ttl"
|
||||||
[ttl & [opts]]
|
[ttl & [opts]]
|
||||||
(let [{:keys [session-atom refresh-on-write refresh-on-read sweep-threshold sweep-interval on-removal] :as opts}
|
(let [{:keys [session-atom refresh-on-write refresh-on-read sweep-interval on-removal] :as opts}
|
||||||
(merge
|
(merge
|
||||||
default-opts
|
default-opts
|
||||||
{:session-atom (atom {})}
|
{:session-atom (atom {})}
|
||||||
|
@ -170,15 +163,14 @@
|
||||||
; any of these times! (no, you don't really need a sweeper thread running multiple times per second ...)
|
; any of these times! (no, you don't really need a sweeper thread running multiple times per second ...)
|
||||||
sweep-interval (* 1000 sweep-interval)
|
sweep-interval (* 1000 sweep-interval)
|
||||||
ttl (* 1000 ttl)
|
ttl (* 1000 ttl)
|
||||||
op-counter (if sweep-threshold (atom 0))
|
|
||||||
thread (Thread.
|
thread (Thread.
|
||||||
^Runnable
|
^Runnable
|
||||||
(fn []
|
(fn []
|
||||||
(try
|
(try
|
||||||
(sweeper-thread session-atom ttl op-counter sweep-threshold sweep-interval on-removal)
|
(sweeper-thread session-atom ttl sweep-interval on-removal)
|
||||||
(catch InterruptedException e))))
|
(catch InterruptedException e))))
|
||||||
store (MemoryAgingStore.
|
store (MemoryAgingStore.
|
||||||
session-atom thread ttl refresh-on-write refresh-on-read op-counter sweep-threshold on-removal)]
|
session-atom thread ttl refresh-on-write refresh-on-read on-removal)]
|
||||||
(.start thread)
|
(.start thread)
|
||||||
store))
|
store))
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
(merge
|
(merge
|
||||||
{:refresh-on-read true
|
{:refresh-on-read true
|
||||||
:refresh-on-write true
|
:refresh-on-write true
|
||||||
:sweep-threshold nil
|
|
||||||
:sweep-interval 15}
|
:sweep-interval 15}
|
||||||
opts)))
|
opts)))
|
||||||
|
|
||||||
|
@ -113,8 +112,7 @@
|
||||||
(testing "Individual session entries are expired appropriately when read, independently of the sweep thread."
|
(testing "Individual session entries are expired appropriately when read, independently of the sweep thread."
|
||||||
(let [as (aging-memory-store
|
(let [as (aging-memory-store
|
||||||
1 ; expire after 1 second
|
1 ; expire after 1 second
|
||||||
{:sweep-threshold 1 ; sweeper thread write threshold is after every single write
|
{:sweep-interval 10 ; sweeper thread tries to run every 10 seconds
|
||||||
:sweep-interval 10 ; sweeper thread tries to run every 10 seconds
|
|
||||||
})]
|
})]
|
||||||
(write-session as "mykey" {:foo 1})
|
(write-session as "mykey" {:foo 1})
|
||||||
(is (= (read-session as "mykey") {:foo 1})
|
(is (= (read-session as "mykey") {:foo 1})
|
||||||
|
@ -123,45 +121,12 @@
|
||||||
(is (nil? (read-session as "mykey"))
|
(is (nil? (read-session as "mykey"))
|
||||||
"session entry should no longer be present"))))
|
"session entry should no longer be present"))))
|
||||||
|
|
||||||
(deftest sweeper-thread-expires-entries-at-interval-only-when-threshold-reached
|
(deftest sweeper-thread-expires-entries-at-interval
|
||||||
(testing "When a threshold is specified, the sweeper thread expires entries whenever it runs only when the operation (write) threshold is reached."
|
(testing "Sweeper thread expires entries whenever it runs."
|
||||||
(let [as (aging-memory-store
|
(let [as (aging-memory-store
|
||||||
1 ; expire after 1 second
|
1 ; expire after 1 second
|
||||||
{:refresh-on-read true
|
{:refresh-on-read true
|
||||||
:refresh-on-write true
|
:refresh-on-write true
|
||||||
:sweep-threshold 5 ; only trigger sweep after 5 writes
|
|
||||||
:sweep-interval 1 ; sweeper thread tries to run every 1 second
|
|
||||||
})]
|
|
||||||
(write-session as "mykey" {:foo 1})
|
|
||||||
(Thread/sleep 2000) ; wait long enough for session ttl to elapse
|
|
||||||
; key should still exist, even though it's expired (not enough writes have occurred)
|
|
||||||
(is (integer? (read-timestamp as "mykey"))
|
|
||||||
"session entry should still be present even though it has expired")
|
|
||||||
|
|
||||||
; key should exist for three more writes
|
|
||||||
(write-session as "other-key" {:foo 1})
|
|
||||||
(is (integer? (read-timestamp as "mykey"))
|
|
||||||
"session entry should still be present even though it has expired")
|
|
||||||
(write-session as "other-key" {:foo 1})
|
|
||||||
(is (integer? (read-timestamp as "mykey"))
|
|
||||||
"session entry should still be present even though it has expired")
|
|
||||||
(write-session as "other-key" {:foo 1})
|
|
||||||
(is (integer? (read-timestamp as "mykey"))
|
|
||||||
"session entry should still be present even though it has expired")
|
|
||||||
|
|
||||||
; on the fifth write and after 1 second, key should not exist
|
|
||||||
(write-session as "other-key" {:foo 1})
|
|
||||||
(Thread/sleep 2000) ; allow time for sweeper thread to run
|
|
||||||
(is (nil? (read-timestamp as "mykey"))
|
|
||||||
"session entry should have been removed now"))))
|
|
||||||
|
|
||||||
(deftest sweeper-thread-expires-entries-at-interval-with-no-threshold-set
|
|
||||||
(testing "When a threshold is NOT specified, the sweeper thread expires entries whenever it runs."
|
|
||||||
(let [as (aging-memory-store
|
|
||||||
1 ; expire after 1 second
|
|
||||||
{:refresh-on-read true
|
|
||||||
:refresh-on-write true
|
|
||||||
:sweep-threshold nil ; no sweeper thread threshold
|
|
||||||
:sweep-interval 1 ; sweeper thread tries to run every 1 second
|
:sweep-interval 1 ; sweeper thread tries to run every 1 second
|
||||||
})]
|
})]
|
||||||
(write-session as "mykey" {:foo 1})
|
(write-session as "mykey" {:foo 1})
|
||||||
|
@ -203,7 +168,6 @@
|
||||||
(let [as (aging-memory-store
|
(let [as (aging-memory-store
|
||||||
1 ; expire after 1 second
|
1 ; expire after 1 second
|
||||||
{:refresh-on-read true
|
{:refresh-on-read true
|
||||||
:sweep-threshold 1 ; sweep runs after every write
|
|
||||||
:sweep-interval 1 ; sweep thread tries to run every 1 second
|
:sweep-interval 1 ; sweep thread tries to run every 1 second
|
||||||
})]
|
})]
|
||||||
(is (nil? (read-session as "foo"))
|
(is (nil? (read-session as "foo"))
|
||||||
|
|
Loading…
Reference in a new issue