View Source Antikythera.Memcache (antikythera v0.5.1)
Easy-to-use in-memory cache for each executor pool.
Antikythera.Memcache behaves as a key-value storage. Cached key-value pairs are internally stored in ETS. It accepts arbitrary (but not too large) terms as both keys and values.
Usage
iex> Antikythera.Memcache.write("foo", "bar", epool_id, 3_600)
:ok
iex> Antikythera.Memcache.read("foo", epool_id)
{:ok, "bar"}
Limits
The number of records and the size of keys and values are limited.
- The maximum number of records for each executor pool
is 100.
- If exceeds the limit, a record nearest to expiration is evicted so that a new record can be inserted.
- The maximum size of keys and values is defined in
Antikythera.Memcache.Key
andAntikythera.Memcache.Value
.- To know how the size of keys and values is calculated, see
Antikythera.TermUtil
. - If exceeds the limit,
write/5
returns an error:too_large_key
or:too_large_value
.
- To know how the size of keys and values is calculated, see
Lifetime of records
There are 2 cases where records in Antikythera.Memcache are evicted:
- Records are expired (see Mechanism of Expiration below for more details)
- Reach the maximum number of records for each executor pool (as mentioned in Limits)
Please note that records in Antikythera.Memcache could be evicted anytime.
Mechanism of Expiration
The lifetime of records must be set as lifetime_in_sec
in write/5
.
This lifetime does not guarantee that records remain in the entire specified lifetime.
To avoid the thundering herd, whether records are expired is decided probabilistically. The probability of expiration is shown in the following.
If the thundering herd becomes a big problem, adjust prob_lifetime_ratio
in write/5
.
Summary
Functions
Read the value associated with the key
from Antikythera.Memcache.
Try to read a value associated with the key
from Antikythera.Memcache and if that fails,
write a value returned by fun
to Antikythera.Memcache.
Write a key-value pair to Antikythera.Memcache.
Functions
@spec read(Antikythera.Memcache.Key.t(), Antikythera.ExecutorPool.Id.t()) :: Croma.Result.t(Antikythera.Memcache.Value.t(), :not_found)
Read the value associated with the key
from Antikythera.Memcache.
Please note that records in Antikythera.Memcache could be evicted anytime so the error handling must be needed.
read_or_else_write(key, epool_id, lifetime_in_sec, prob_lifetime_ratio \\ 0.9, fun)
View Source@spec read_or_else_write( Antikythera.Memcache.Key.t(), Antikythera.ExecutorPool.Id.t(), non_neg_integer(), Antikythera.Memcache.NormalizedFloat.t(), (() -> Antikythera.Memcache.Value.t()) ) :: Croma.Result.t( Antikythera.Memcache.Value.t(), :too_large_key | :too_large_value )
Try to read a value associated with the key
from Antikythera.Memcache and if that fails,
write a value returned by fun
to Antikythera.Memcache.
fun
is evaluated only if a value is not found,
and the new value returned by fun
is stored in Antikythera.Memcache.
If a value is found in Antikythera.Memcache or writing the new value to Antikythera.Memcache succeeds,
the value is returned as {:ok, value}
, but if writing the new value fails, an error is returned in the same manner as write/5
.
Parameters lifetime_in_sec
and prob_lifetime_ratio
are used to call write/5
and the details are described above.
write(key, value, epool_id, lifetime_in_sec, prob_lifetime_ratio \\ 0.9)
View Source@spec write( Antikythera.Memcache.Key.t(), Antikythera.Memcache.Value.t(), Antikythera.ExecutorPool.Id.t(), non_neg_integer(), Antikythera.Memcache.NormalizedFloat.t() ) :: :ok | {:error, :too_large_key | :too_large_value}
Write a key-value pair to Antikythera.Memcache.
See above descriptions for more details.