A generic, in-memory caching application based on ETS.
Cache = kache:start_link([compressed]),
kache:put(Cache, item1, value1),
{ok, value1} = kache:get(Cache, item1),
kache:remove(Cache, item1),
notfound = kache:get(Cache, item1),
kache:stop(Cache).
See our changelog.
- Simple key/value interface
- Automatic, per-item time-to-live
- Optional capacity limit with multiple eviction strategies
- Synchronized cache get-or-fill API to avoid stampeding
The public library interface is implemented in the kache
module.
Use start_link
to create a new cache. The behavior of the
cache can be tuned through the options proplist
. To destroy the
cache, call stop
.
Cache = kache:start_link([]),
kache:stop(Cache).
The simplest interface to a cache simply treats it as a key-value
store with the put
, get
, remove
, and purge
functions.
kache:put(Cache, Key, Value, TimeToLive),
{ok, Value} = kache:get(Cache, Key),
kache:remove(Cache, Key),
kache:purge(Cache).
Each entry in the cache has an associated time-to-live. There are two mechanisms to remove expired entries from the cache.
-
The time-to-live is evaluated on each
get
and stale entries automatically removed before the function returnsnotfound
. -
The
sweep
function performs a full cache scan and removes all stale items.
For a cache with heavy read-to-write ratio, the simple key/value
interface may be insufficient to properly protect the underlying
resource. In this case, the get_wait
and get_fill
functions
provide a mechanism to limit the number of processes competing to put
a value into the cache.
The function get_wait
returns immediately with {ok, Value}
if a
value is already cached. If not, it waits for a value to be put
into the cache, or the specified Timeout
to expire. In case of a
timeout or an explicit remove
, it returns notfound
.
timer:apply_after(Delay, kache, put, [Cache, Key, Value]),
{ok, Value} = kache:get_wait(Cache, Key, Timeout).
The function get_fill
, when no value is cached and no other process
is already running get_fill
, calls the Generator
argument to
produce a value and puts it into the cache. Otherwise, it behaves as
get_wait
.
{ok, Value} = kache:get_fill(Cache, Key, Generator, Timeout).
An eviction strategy is any module that implements the
kache_eviction
behavior. Four eviction
strategies are included
none
- does not evict anything and does not enforce the capacity limitfifo
- evicts in order of insertion, oldest entries firstlru
- evicts in order of use, longest unread entries firstrandom
- evicts in randomized order
The function evict
asks the eviction strategy to remove at least N
entries from the cache. Depending on the eviction strategy, any
number of entries might actually be removed, including none and all..
Cache = kache:start_link([{eviction, lru}, {capacity, 1024}]),
kache:evict(Cache, N),
See our guide on contributing.
Kache is using rebar3
.
$ rebar3 compile
$ rebar3 shell
The accompanying Makefile
has a target to run unit tests and some
code analysis with elvis
, xref
, and dialyzer
.
$ make ci
Copyright © 2020 Klarna Bank AB
For license details, see the LICENSE file in the root of this project.