Kache
A generic, in-memory caching application based on ETS.
Install / Use
/learn @klarna-incubator/KacheREADME
Kache - Smoooth Caching
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).
Release History
See our changelog.
Features
- 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
Usage
The public library interface is implemented in the kache
module.
Creation/Destruction
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).
Key/value Interface
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).
Entry Expiration
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
getand stale entries automatically removed before the function returnsnotfound. -
The
sweepfunction performs a full cache scan and removes all stale items.
Synchronized Interface
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).
Cache Capacity and Eviction Strategies
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),
Contributing
See our guide on contributing.
Development Setup
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
License
Copyright © 2020 Klarna Bank AB
For license details, see the LICENSE file in the root of this project.
<!-- Markdown link & img dfn's -->