Simple clojure wrapper over Caffeine.
hive-agi fork. Published as
io.github.hive-agi/cloffeineso hive projects can use caffeine 3.2.4 while AppsFlyer/cloffeine#16 is pending upstream. Namespaces are unchanged (cloffeine.*), so it is a drop-in replacement forcom.appsflyer/cloffeine. Once the PR lands, switch back to upstream.;; deps.edn :mvn/repos {"hive-gitea" {:url "https://gitea.hive-mcp.com/api/packages/hive-agi/maven"}} :deps {io.github.hive-agi/cloffeine {:mvn/version "1.1.0"}}Releases are cut locally:
clojure -T:build bump :level :patchthenclojure -T:build deploy.
Add [com.appsflyer/cloffeine "1.1.0"] to your project.clj under :dependencies,
or com.appsflyer/cloffeine {:mvn/version "1.1.0"} to your deps.edn.
lein test # or: clojure -X:test
The suite has three parts: example-based tests (cloffeine.core-test),
property-based tests over generated keys, values and operation sequences
(cloffeine.property-test), and a mutation-testing suite
(cloffeine.mutation-test) that injects defects into cloffeine.common at load
time and asserts each one is detected by the tests.
(require '[cloffeine.cache :as cache])
(require '[clojure.test :refer [is]])
(def cache (cache/make-cache))
(cache/put! cache :key :v)
(is (= :v (cache/get cache :key name)))
(cache/invalidate! cache :key)
(is (= "key" (cache/get cache :key name)))
(require '[cloffeine.loading-cache :as loading-cache])
(require '[cloffeine.common :as common])
(def loads (atom 0))
(def cl (common/reify-cache-loader (fn [k]
(swap! loads inc)
(name k))))
(def lcache (loading-cache/make-cache cl))
(loading-cache/put! lcache :key :v)
(is (= :v (loading-cache/get lcache :key)))
(is (= 0 @loads))
(loading-cache/invalidate! lcache :key)
(is (= "key" (loading-cache/get lcache :key)))
(is (= 1 @loads))
(is (= "key" (loading-cache/get lcache :key name)))
(is (= 1 @loads))
(is (= "key" (cache/get lcache :key name)))
(is (= 1 @loads))
(cache/invalidate! lcache :key)
(is (= "key" (cache/get lcache :key name)))
(is (= 1 @loads))
Since caffeine 3.1.0, a read that finds a :refreshAfterWrite deadline elapsed may
return the refreshed value rather than the stale one — the reload is computed by the
caller when possible. The read never blocks on the reload, and a reload that throws
(or a rejected promise, for the async loaders) leaves the previous value in place.
(def lcache (loading-cache/make-cache cl {:refreshAfterWrite 10 :timeUnit :s}))
;; equivalently, with a java.time.Duration
(def lcache (loading-cache/make-cache cl {:refreshAfterWrite (java.time.Duration/ofSeconds 10)}))
;; by entry count
(cache/make-cache {:maximumSize 10000})
;; by weight — :weigher requires :maximumWeight
(def weigher (common/reify-weigher (fn [_this _k v] (count v))))
(cache/make-cache {:maximumWeight 1000 :weigher weigher})
(require '[cloffeine.async-cache :as async-cache])
(require '[promesa.core :as p])
(def acache (async-cache/make-cache))
(async-cache/put! acache :key (p/resolved :v))
(is (= :v @(async-cache/get acache :key name)))
(async-cache/invalidate! acache :key)
(is (= "key" @(async-cache/get acache :key name)))
(require '[cloffeine.async-loading-cache :as async-loading-cache])
(def alcache (async-loading-cache/make-cache (common/reify-cache-loader name)))
(async-loading-cache/put! alcache :key (p/resolved :v))
(is (= :v @(async-loading-cache/get alcache :key name)))
(async-loading-cache/invalidate! alcache :key)
(is (= "key" @(async-loading-cache/get alcache :key name)))
Can you improve this documentation? These fine people already did:
Ido Barkan, Andrey Batyuk, Pedro Gomes Branquinho & asaf.cheloucheEdit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |