diff --git a/src/aging_session/core.clj b/src/aging_session/core.clj index 5820f96..9b7ff5d 100644 --- a/src/aging_session/core.clj +++ b/src/aging_session/core.clj @@ -73,7 +73,7 @@ (all-entries [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 (read-timestamp [_ key] (get-in @session-atom [key :timestamp])) @@ -97,8 +97,6 @@ nil))))) (write-session [_ key data] - (if op-threshold - (swap! op-counter inc)) (let [key (or key (unique-id))] (if on-removal ; when we have an on-removal listener, we need to check if we are overwriting an entry @@ -128,13 +126,9 @@ (defn- sweeper-thread "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 [] - (let [[old new] (if op-threshold - (when (>= @op-counter op-threshold) - (reset! op-counter 0) - (swap-vals! session-atom sweep-session ttl)) - (swap-vals! session-atom sweep-session ttl))] + (let [[old new] (swap-vals! session-atom sweep-session ttl)] (if (and on-removal (not= old new)) ; TODO: is there a faster way to get the keys difference? maybe this is fine ... ? @@ -153,13 +147,12 @@ (def default-opts {:refresh-on-write true :refresh-on-read true - :sweep-threshold nil :sweep-interval 30}) (defn aging-memory-store "Creates an in-memory session storage engine where entries expire after the given ttl" [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 default-opts {: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 ...) sweep-interval (* 1000 sweep-interval) ttl (* 1000 ttl) - op-counter (if sweep-threshold (atom 0)) thread (Thread. ^Runnable (fn [] (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)))) 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) store)) diff --git a/test/aging_session/core_test.clj b/test/aging_session/core_test.clj index 90b2933..f393d8e 100644 --- a/test/aging_session/core_test.clj +++ b/test/aging_session/core_test.clj @@ -11,7 +11,6 @@ (merge {:refresh-on-read true :refresh-on-write true - :sweep-threshold nil :sweep-interval 15} opts))) @@ -113,8 +112,7 @@ (testing "Individual session entries are expired appropriately when read, independently of the sweep thread." (let [as (aging-memory-store 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}) (is (= (read-session as "mykey") {:foo 1}) @@ -123,45 +121,12 @@ (is (nil? (read-session as "mykey")) "session entry should no longer be present")))) -(deftest sweeper-thread-expires-entries-at-interval-only-when-threshold-reached - (testing "When a threshold is specified, the sweeper thread expires entries whenever it runs only when the operation (write) threshold is reached." +(deftest sweeper-thread-expires-entries-at-interval + (testing "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 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 })] (write-session as "mykey" {:foo 1}) @@ -203,7 +168,6 @@ (let [as (aging-memory-store 1 ; expire after 1 second {:refresh-on-read true - :sweep-threshold 1 ; sweep runs after every write :sweep-interval 1 ; sweep thread tries to run every 1 second })] (is (nil? (read-session as "foo"))