Nebulex v1.2.2 Nebulex.Adapters.Multilevel View Source
Adapter module for Multi-level Cache.
This is just a simple layer on top of local or distributed cache
implementations that enables to have a cache hierarchy by levels.
Multi-level caches generally operate by checking the fastest,
level 1 (L1) cache first; if it hits, the adapter proceeds at
high speed. If that first cache misses, the next fastest cache
(level 2, L2) is checked, and so on, before accessing external
memory (that can be handled by a
For write functions, the "Write Through" policy is applied by default;
this policy ensures that the data is stored safely as it is written
throughout the hierarchy. However, it is possible to force the write
operation in a specific level (although it is not recommended) via
level option, where the value is a positive integer greater than 0.
These options can be set through the config file:
:cache_model- Specifies the cache model:
:exclusive; defaults to
:inclusive. In an inclusive cache, the same data can be present in all caches/levels. In an exclusive cache, data can be present in only one cache/level and a key cannot be found in the rest of caches at the same time. This option affects
getoperation only; if
:inclusive, when the key is found in a level N, that entry is duplicated backwards (to all previous levels: 1..N-1).
:levels- The list of caches where each cache corresponds to a level. The order of the caches in the list defines the the order of the levels as well, for example, the first cache in the list will be the L1 cache (level 1) and so on; the Nth elemnt will be the LN cache. This option is mandatory, if it is not set or empty, an exception will be raised.
:fallback- Defines a fallback function when a key is not present in any cache level. Function is defined as:
(key -> value).
:fallback can be defined in two ways: at compile-time and at run-time.
At compile-time, in the cache config, set the module that implements the
config :my_app, MyApp.MultilevelCache, fallback: &MyMapp.AnyModule/1
And at run-time, passing the function as an option within the
(only valid for
MultilevelCache.get("foo", fallback: fn(key) -> key * 2 end)
Some functions below accept the following options:
:level- It may be an integer greater than 0 that specifies the cache level where the operation will take place. By default, the evaluation is performed throughout the whole cache hierarchy (all levels).
Nebulex.Cache is the wrapper around the Cache. We can define the
multi-level cache as follows:
defmodule MyApp.MultilevelCache do use Nebulex.Cache, otp_app: :nebulex, adapter: Nebulex.Adapters.Multilevel defmodule L1 do use Nebulex.Cache, otp_app: :nebulex, adapter: Nebulex.Adapters.Local end defmodule L2 do use Nebulex.Cache, otp_app: :nebulex, adapter: Nebulex.Adapters.Partitioned end def fallback(_key) do # maybe fetch the data from Database nil end end defmodule MyApp.LocalCache do use Nebulex.Cache, otp_app: :my_app, adapter: Nebulex.Adapters.Local end
Where the configuration for the Cache must be in your application
environment, usually defined in your
config :my_app, MyApp.MultilevelCache, levels: [ MyApp.MultilevelCache.L1, MyApp.MultilevelCache.L2 ], fallback: &MyApp.MultilevelCache.fallback/1 config :my_app, MyApp.MultilevelCache.L1, n_shards: 2, gc_interval: 3600 config :my_app, MyApp.MultilevelCache.L2, primary: MyApp.LocalCache config :my_app, MyApp.LocalCache, n_shards: 2, gc_interval: 3600
Using the multilevel cache cache:
# Retrieving data from cache MyCache.get("foo", fallback: fn(_key) -> # Maybe fetch the key from database "initial value" end) # Entry is set in all cache levels MyCache.set("foo", "bar") # Entry is set at second cache level MyCache.set("foo", "bar", level: 2) # Entry is deleted from all cache levels MyCache.delete("foo") # Entry is deleted from second cache level MyCache.delete("foo", level: 2)
This adapter provides some additional functions to the
This function returns the configured level list.
This function returns the multi-level cache model.
This function returns the default fallback function.
Because this adapter reuses other existing/configured adapters, it inherits all their limitations too. Therefore, it is highly recommended to check the documentation of the used adapters.