Nebulex.Adapters.Multilevel (Nebulex v2.0.0-rc.2) 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 cacheable decorator).

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.

We can define a multi-level cache as follows:

defmodule MyApp.Multilevel 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
end

Where the configuration for the cache and its levels must be in your application environment, usually defined in your config/config.exs:

config :my_app, MyApp.Multilevel,
  model: :inclusive,
  levels: [
    {
      MyApp.Multilevel.L1,
      gc_interval: :timer.seconds(3600) * 12,
      backend: :shards
    },
    {
      MyApp.Multilevel.L2,
      primary: [
        gc_interval: :timer.seconds(3600) * 12,
        backend: :shards
      ]
    }
  ]

If your application was generated with a supervisor (by passing --sup to mix new) you will have a lib/my_app/application.ex file containing the application start callback that defines and starts your supervisor. You just need to edit the start/2 function to start the cache as a supervisor on your application's supervisor:

def start(_type, _args) do
  children = [
    {MyApp.Multilevel, []},
    ...
  ]

See Nebulex.Cache for more information.

Options

This adapter supports the following options and all of them can be given via the cache configuration:

  • :levels - This option is to define the levels, a list of tuples {cache_level :: Nebulex.Cache.t(), opts :: Keyword.t()}, where the first element is the module that defines the cache for that level, and the second one is the options that will be passed to that level in the start/link/1 (which depends on the adapter this level is using). The order in which the levels are defined is the same the multi-level cache will use. For example, the first cache in the list will be the L1 cache (level 1) and so on; the Nth element will be the LN cache. This option is mandatory, if it is not set or empty, an exception will be raised.

  • :model - Specifies the cache model: :inclusive or :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 get operation only; if :cache_model is :inclusive, when the key is found in a level N, that entry is duplicated backwards (to all previous levels: 1..N-1).

Shared options

Almost all of the cache functions outlined in Nebulex.Cache module 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).

Extended API

This adapter provides one additional convenience function for retrieving the cache model for the given cache name:

MyCache.model()
MyCache.model(:cache_name)

Caveats of multi-level adapter

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 adapters to use.